Laravel orderby 加入 2 个没有雄辩关系的表

Posted

技术标签:

【中文标题】Laravel orderby 加入 2 个没有雄辩关系的表【英文标题】:Laravel orderby joining 2 tables without eloquent relationship 【发布时间】:2021-06-22 04:13:53 【问题描述】:

我有 2 张桌子用于聊天系统

“用户”表结构:

id name

“消息”表结构:

id sender_id receiver_id message

我想返回上次你和朋友聊天时订购的朋友用户。 注意:id时间戳相同

假设,

id sender_id receiver_id message
1 $userA->id $userB->id abc
2 $userC->id $userA->id xyz

所以,如果 $userA 是登录用户 - 我希望用户返回如下:

[
    0 => $userC,
    1 => $userB,
    2 => $userD,
    3 => $userE,
    4 => $userF,
    ...
]

(其中$userD$userE$userF 没有与用户$userA 的消息)

基本上,如果用户与登录用户有任何消息,我想返回所有使用排序的朋友用户。

我当前的代码给了我一些意想不到的结果 -

return DB::table('users')->leftJoin('messages', function ($join) 
    $join->on('users.id', '=', 'messages.sender_id')
        ->where('messages.sender_id', auth()->id())
        ->orOn('users.id', '=', 'messages.receiver_id')
        ->where('messages.receiver_id', auth()->id());
)
->select('users.*')
->where('users.id', '!=', auth()->id())
->orderBy('messages.id', 'asc')
->get();

【问题讨论】:

【参考方案1】:

老实说,我无法确定这是否可行,因为我无法测试它,但我认为代码应该是这样的:

$messagesSent = DB::table('messages')
    ->select('sender_id as other_user', DB::raw('MAX(id) as last_message_id'))
    ->where('receiver_id', auth()->id())
    ->groupBy('sender_id');

$messagesSentOrReceived = DB::table('messages')
    ->select('receiver_id as other_user', DB::raw('MAX(id) as last_message_id'))
    ->where('sender_id', auth()->id())
    ->groupBy('receiver_id')
    ->union($messagesSent);

$usersWithCommunication = DB::table('users')
    ->select('other_user', DB::raw('MAX(last_message_id) as last_message_id'))
    ->joinSub($messagesSentOrReceived, 'latest_messages', function ($join) 
        $join->on('users.id', '=', 'latest_messages.other_user');
    )
    ->groupBy('other_user');
    

return DB::table('users')
    ->leftJoinSub($usersWithCommunication, 'latest_communications', function ($join) 
        $join->on('users.id', '=', 'latest_communications.other_user');
    )
    ->select('users.*')
    ->orderBy('latest_communications.last_message_id', 'asc')
    ->get();

【讨论】:

只有存在任何消息时才会显示用户。实际上,我希望这些用户居于首位,而其余用户则居于其后。您的代码解决了我的排序问题。有了这个,我还希望其余的用户位于底部。谢谢 最后我用 leftJoinSub 作为回报解决了 @DebarshiDas 编辑了我的答案,以便正确回答问题。我的代码真的没有错误吗?我确信我会搞砸一些事情,因为我实际上无法测试任何东西 我这里还有一个问题!我没有加载所有用户,而是绑定了分页。但是,当我在 return 方法中执行 paginate(10) 而不是 get() 时,我总是会得到一个与其他 9 个用户重复的用户。但是如果我这样做 get() 则数组中没有重复的用户。我不知道问题出在哪里! @DebarshiDas 如果您创建了新问题,那将是首选。您可以获得更多答案并指定更多信息

以上是关于Laravel orderby 加入 2 个没有雄辩关系的表的主要内容,如果未能解决你的问题,请参考以下文章

加入彼此不相关的表laravel

Laravel orderBy和groupBy with if statement

Laravel 5:如何使用 'where' 或 'orderBy' 使用 eloquent?

laravel框架orderBy问题

Laravel 5 - 多维 groupBy、orderBy 和 paginate

Laravel:orderBy喜欢计数