合并和排序两个雄辩的集合?

2022-08-31 00:04:38

我有两个集合,我想将其合并到一个变量中(当然,按一个集合排序 - )。我该怎么做?created_at

我的控制器看起来:

$replies = Ticket::with('replies', 'replies.user')->find($id);
$logs = DB::table('logs_ticket')
        ->join('users', 'users.id', '=', 'mod_id')
        ->where('ticket_id', '=', $id)
        ->select('users.username', 'logs_ticket.created_at', 'action')
        ->get();

例如,我的输出看起来:

答复:

ID | ticket_id | username | message | created_at
1  | 1         | somebody | asdfghj | 2014-04-12 12:12:12
2  | 1         | somebody | qwertyi | 2014-04-14 12:11:10

原木:

ID | ticket_id | username | action | created_at
1  | 1         | somebody | close  | 2014-04-13 12:12:14
2  | 1         | somebody |  open  | 2014-04-14 14:15:10

我想要这样的东西:

ticket_id | table | username | message | created_at
1         |replies| somebody | asdfghj | 2014-04-12 12:12:12
1         | logs  | somebody |  close  | 2014-04-13 12:12:14
1         | logs  | somebody |  open   | 2014-04-14 11:15:10
1         |replies| somebody | qwertyi | 2014-04-14 12:11:10

编辑:

我的票证模型看起来:

<?php

class Ticket extends Eloquent {

    protected $table = 'tickets';

    public function replies() {
        return $this->hasMany('TicketReply')->orderBy('ticketreplies.created_at', 'desc');
    }

    public function user()
    {
        return $this->belongsTo('User');
    }
}
?>

答案 1

针对您的问题的一些解决方法。

$posts = collect(Post::onlyTrashed()->get());
$comments = collect(Comment::onlyTrashed()->get());

$trash = $posts->merge($comments)->sortByDesc('deleted_at');

这样,即使存在重复的ID,您也可以合并它们。


答案 2

您将无法轻松获得您想要的。

通常,使用 和 排序应易于,而使用 进行排序。但是,由于没有唯一的ID,合并将无法按您希望的方式工作,并且所需的“表”列必须手动进行。$collection->merge($otherCollection);$collection->sort();

此外,我认为它们实际上都是不同类型的集合(一个基于 will 是 ,另一个是标准),这可能会导致它自己的问题。因此,我建议对两者都使用 DB::table(),并使用您可以控制的列来扩充结果。Eloquent\ModelEloquent\CollectionCollection

至于实现此目的的代码,我不确定,因为我在Laravel中没有做很多低级数据库工作,所以不知道创建查询的最佳方法。无论哪种方式,只是因为通过两个查询和一些PHP合并来管理它看起来很痛苦,我建议在一个数据库查询中完成所有这些操作。它实际上看起来更整洁,可以说更易于维护:

您需要的 SQL 如下所示:

SELECT * FROM
(
    SELECT
        `r`.`ticket_id`,
        'replies' AS `table`,
        `u`.`username`,
        `r`.`message`,
        `r`.`created_at`
    FROM `replies` AS `r`
    LEFT JOIN `users` AS `u`
        ON `r`.`user_id` = `u`.`id`
    WHERE `r`.`ticket_id` = ?
) UNION (
    SELECT
        `l`.`ticket_id`,
        'logs' AS `table`,
        `u`.`username`,
        `l`.`action` AS `message`,
        `l`.`created_at`
    FROM `logs` AS `l`
    LEFT JOIN `users` AS `u`
        ON `l`.`user_id` = `u`.`id`
    WHERE `l`.ticket_id` = ?
)
ORDER BY `created_at` DESC

这是非常不言自明的:执行两个查询,返回相同的列,然后对MySQL中的结果集进行排序。希望它(或类似的东西,因为我不得不猜测你的数据库结构)会为你工作。UNION

至于将其转换为Laravel风格的查询,我想这取决于您。DB::


推荐