Laravel雄辩地合并两个结果并排序

时间:2019-09-12 14:07:34

标签: php laravel sorting eloquent

我发现了很多有关此问题的帖子,但没有解决方案。

可能是因为我的Laravel版本。 5.7。

我有两个结果,看起来像这样:

result_a = DB::connection('mysql_live')->table('user_chatmessages')
->where('from_user', $data->chat_from_user)->get();

$result_b = DB::connection('mysql_live')->table('user_chatmessages')
->where('to_user', $data->chat_from_user)->get();

现在,我将它们合并,效果很好:

$merged = $result_a->merge($result_b);
$result = $merged->values()->sortByDesc('date_added');

排序不会影响整个结果。问题在于排序方式是先排序result_a,然后排序result_b

我尝试了很多不同的语法变体:

$result = $result_a->merge($result_b)->sortBy('date_added');

$merged = $result_a->merge($result_b);
$result = $merged->sortByDesc('date_added');

$merged = $result_a->merge($result_b)->sortByDesc('date_added');
$result = $merged->all();

$result = ($result_a->merge($result_b))->sortBy('date_added');

可能还要更多的时间,我已经在这个问题上坐了很长一段时间,我发现所有的线程看起来超级简单,人们告诉它可行。

我还尝试按ID进行排序,结果相同。

编辑

@ N69S提供的替代解决方案适用于想要获取某个用户的所有收发消息的情况。

但是如何使用相同的方法在两个特定用户之间获取消息?例如,我想获取ID为1的用户和ID为2的用户之间的聊天消息,这将不起作用:

$result = DB::connection('mysql_live')
                    ->table('user_chatmessages')
                    ->where('from_user', $data->chat_from_user)
                    ->where('to_user', $data->chat_to_user)
                    ->orWhere('from_user', $data->chat_to_user)
                    ->orWhere('to_user', $data->chat_from_user)
                    ->orderBy('date_added', 'desc')
                    ->get();

我现在正在尝试的内容如下:

$result = DB::connection('mysql_live')->table('user_chatmessages')
    ->where(function ($query) use ($from, $to) {
        $query->where('from_user', $from)->where('to_user', $to);
    })->orWhere(function ($query) {
        $query->where('from_user', $to)->where('to_user', $from);
    })->orderBy('date_added', 'asc')->get();

但是我得到一个错误:从&到未定义。

这很完美:

$result = DB::connection('mysql_live')->table('user_chatmessages')
        ->where(function ($query) {
            $query->where('from_user', '1')->where('to_user', '2');
        })->orWhere(function ($query) {
            $query->where('from_user', '2')->where('to_user', '1');
        })->orderBy('date_added', 'asc')->get();

3 个答案:

答案 0 :(得分:2)

您为什么不在一个查询中恢复所有结果?

result_a = DB::connection('mysql_live')
    ->table('user_chatmessages')
    ->where('from_user', $data->chat_from_user)
    ->orWhere('to_user', $data->chat_from_user)
    ->orderBy('date_added', 'desc')
    ->get();

或用户->orderBy('created_at', 'desc')(如果您具有默认时间戳字段)

编辑

要恢复两个特定用户之间的聊天,您需要使用括号。

result_a = DB::connection('mysql_live')
    ->table('user_chatmessages')
    ->where(function($query) use($data) {
        $query->where('from_user', $data->chat_from_user)
            ->where('to_user', $data->chat_to_user);
    })
    ->orWhere(function($query) use($data) {
        $query->where('to_user', $data->chat_from_user)
            ->where('from_user', $data->chat_to_user);
    })
    ->orderBy('date_added', 'desc')
    ->get();

答案 1 :(得分:0)

您可以直接获取数据,而无需使用像这样的合并:

result = DB::connection('mysql_live')
         ->table('user_chatmessages')
         ->where(function($query) use ($data){
           $query->where('from_user', $data->chat_from_user)->orWhere('to_user', $data->chat_from_user)
         })->orderBy('date_added','desc')
           ->get();

答案 2 :(得分:0)

如果要使用两个查询,则可以使用并集。

子查询

$subQuery = DB::connection('mysql_live')
->table('user_chatmessages')
->where('from_user', $data->chat_from_user);

通过在主查询上使用并集来添加子查询

$results = DB::connection('mysql_live')
->table('user_chatmessages')
->where('to_user', $data->chat_from_user)
->union($subQuery)                         //see
->orderBy('date_added', 'desc')            //see
->get();

这应该有效。您可以使用任何查询,只要将它们合并即可避免合并到集合中,然后按date_added排序