Laravel orderby join 2 tables without eloquent relationship
Laravel orderby joining 2 tables without eloquent relationship
我有2个table聊天系统
“用户” table 结构:
id
name
"消息" table 结构:
id
sender_id
receiver_id
message
我想return好友用户按上次你和好友聊天时排序。
注意:id
与 timestamp
相同
假设,
id
sender_id
receiver_id
message
1
$userA->id
$userB->id
abc
2
$userC->id
$userA->id
xyz
所以,如果 $userA
是登录用户 - 我希望用户 return 像:
[
0 => $userC,
1 => $userB,
2 => $userD,
3 => $userE,
4 => $userF,
...
]
(其中 $userD
、$userE
、$userF
没有与用户 $userA
的消息)
基本上我想 return 如果用户有任何与登录用户的消息,则使用排序的所有朋友用户。
我当前的代码给了我一些意想不到的结果 -
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();
老实说,我无法确定这是否有效,因为我无法对其进行测试,但我认为代码应该类似于:
$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();
我有2个table聊天系统
“用户” table 结构:
id | name |
---|
"消息" table 结构:
id | sender_id | receiver_id | message |
---|
我想return好友用户按上次你和好友聊天时排序。
注意:id
与 timestamp
假设,
id | sender_id | receiver_id | message |
---|---|---|---|
1 | $userA->id |
$userB->id |
abc |
2 | $userC->id |
$userA->id |
xyz |
所以,如果 $userA
是登录用户 - 我希望用户 return 像:
[
0 => $userC,
1 => $userB,
2 => $userD,
3 => $userE,
4 => $userF,
...
]
(其中 $userD
、$userE
、$userF
没有与用户 $userA
的消息)
基本上我想 return 如果用户有任何与登录用户的消息,则使用排序的所有朋友用户。
我当前的代码给了我一些意想不到的结果 -
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();
老实说,我无法确定这是否有效,因为我无法对其进行测试,但我认为代码应该类似于:
$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();