将相同的 table 加入多个列并获取包含用户数据的最新记录
join same table with multiple columns and get the latest record with user data
我有两个 table 名为 users 和 message,我想加入两个 tables并从每个用户与用户名的对话中获取最后一条消息。
我想要两个用户之间按时间戳记的最后一条消息,无论是 from_id 还是 to_id,以及同样,希望与我进行过任何对话的每个用户的最后一条消息。
messages table 具有列 from_id、to_id、messages.
下面是我的代码。
$chats = DB::table('users')
->leftJoin('messages', function($query)
{
$query->on('users.id', '=', 'messages.to_id')
->whereRaw('messages.id IN (select MAX(messages.id) from messages join users on users.id = messages.to_id group by users.id)');
})
->select('users.id as user_id', 'users.name', DB::raw('CONCAT("https://www.interwebs.co.in/puzzle/attach/", users.avatar) AS image') , 'users.mobile', 'messages.id', 'messages.from_id', 'messages.to_id', 'messages.body as message', 'messages.attachment', 'messages.seen as seen_count', 'messages.created_at')
->where('messages.from_id', $request->user_id)
->get();
我的消息table是
| from_id | to_id | message | created_at |
| ---------| --------- | ---------| ------------------ |
| 1 | 2 | abc | 2022-02-04 10:55:34 |
| 2 | 1 | cdef | 2022-02-05 10:56:34 |
| 1 | 3 | defg | 2022-02-06 10:57:34 |
| 1 | 3 | hijk | 2022-02-07 10:58:34 |
| 1 | 2 | lmop | 2022-02-08 10:59:34 |
我试过了,但它给我的是当前登录用户每次对话的最后一条消息,而不是其他用户。
我最好使用 sql 来获取数据。首先你需要得到 created_at 的 Max 按 from_id 和 to_id 分组,然后在三个字段 from_id 上将结果连接到相同的 table,to_id 和 created_at。您还可以将用户 table 作为别名 (from_user/to_user)...
同时附加到 from_id 和 to_id
第一个查询给出 from_id、to_id、last_message_created_at:
SELECT
from_id,
to_id,
max(created_at) last_message_created_at
FROM messages
GROUP BY from_id, to_id
将结果与原始邮件 table 合并,如下所示。最后的 SQL 会是这样的。
SELECT
from_user.id,
to_user.id,
msgs.message,
msgs.created_at
# add any additional field from msgs/from_user/to_user aliases as required
FROM messages msgs
JOIN ( #join the first query above here
SELECT
from_id,
to_id,
max(created_at) last_message_created_at
FROM messages
GROUP BY from_id, to_id
) last_msgs ON
(msgs.from_id = last_msgs.from_id
AND msgs.to_id = last_msgs.to_id
AND msgs.created_at = last_msgs.last_message_created_at)
JOIN users from_user on from_user.id = msgs.from_id
JOIN users to_user on to_user.id = msgs.to_id
使用Laravel 函数DB::select 将查询结果提取到数组中。将上面的sql字符串放入一个变量$sql
$results_array = DB::select($sql)
了解 DB::select here。您还可以使用参数化查询。
和here是Laravel
中运行原始sql查询的一些示例
我用下面的代码得到了预期的输出。
我知道我的代码有一些改进,但现在可以正常使用。
$user_id = $request->user_id;
$user_name = DB::table('users')->where('id', $user_id)->value('name');
$chats =DB::table('messages')
->leftJoin('users as u1', 'messages.from_id', '=', 'u1.id')
->leftJoin('users as u2', 'messages.to_id', '=', 'u2.id')
->select('u1.id as user_id', 'u1.name', 'u2.name as name2', 'messages.id','messages.from_id',
'messages.to_id', 'messages.body as message', 'messages.attachment', 'messages.created_at')
->where('messages.from_id', $user_id)
->orWhere('messages.to_id', $user_id)
->latest()
->get();
foreach($chats as $chat)
{
$chat->user_id = $chat->from_id == $user_id ? $chat->to_id : $chat->from_id;
$chat->name = $chat->name == $user_name ? $chat->name2 : $chat->name;
}
$chats = $chats->unique('user_id');
我有两个 table 名为 users 和 message,我想加入两个 tables并从每个用户与用户名的对话中获取最后一条消息。
我想要两个用户之间按时间戳记的最后一条消息,无论是 from_id 还是 to_id,以及同样,希望与我进行过任何对话的每个用户的最后一条消息。
messages table 具有列 from_id、to_id、messages.
下面是我的代码。
$chats = DB::table('users')
->leftJoin('messages', function($query)
{
$query->on('users.id', '=', 'messages.to_id')
->whereRaw('messages.id IN (select MAX(messages.id) from messages join users on users.id = messages.to_id group by users.id)');
})
->select('users.id as user_id', 'users.name', DB::raw('CONCAT("https://www.interwebs.co.in/puzzle/attach/", users.avatar) AS image') , 'users.mobile', 'messages.id', 'messages.from_id', 'messages.to_id', 'messages.body as message', 'messages.attachment', 'messages.seen as seen_count', 'messages.created_at')
->where('messages.from_id', $request->user_id)
->get();
我的消息table是
| from_id | to_id | message | created_at |
| ---------| --------- | ---------| ------------------ |
| 1 | 2 | abc | 2022-02-04 10:55:34 |
| 2 | 1 | cdef | 2022-02-05 10:56:34 |
| 1 | 3 | defg | 2022-02-06 10:57:34 |
| 1 | 3 | hijk | 2022-02-07 10:58:34 |
| 1 | 2 | lmop | 2022-02-08 10:59:34 |
我试过了,但它给我的是当前登录用户每次对话的最后一条消息,而不是其他用户。
我最好使用 sql 来获取数据。首先你需要得到 created_at 的 Max 按 from_id 和 to_id 分组,然后在三个字段 from_id 上将结果连接到相同的 table,to_id 和 created_at。您还可以将用户 table 作为别名 (from_user/to_user)...
同时附加到 from_id 和 to_id第一个查询给出 from_id、to_id、last_message_created_at:
SELECT
from_id,
to_id,
max(created_at) last_message_created_at
FROM messages
GROUP BY from_id, to_id
将结果与原始邮件 table 合并,如下所示。最后的 SQL 会是这样的。
SELECT
from_user.id,
to_user.id,
msgs.message,
msgs.created_at
# add any additional field from msgs/from_user/to_user aliases as required
FROM messages msgs
JOIN ( #join the first query above here
SELECT
from_id,
to_id,
max(created_at) last_message_created_at
FROM messages
GROUP BY from_id, to_id
) last_msgs ON
(msgs.from_id = last_msgs.from_id
AND msgs.to_id = last_msgs.to_id
AND msgs.created_at = last_msgs.last_message_created_at)
JOIN users from_user on from_user.id = msgs.from_id
JOIN users to_user on to_user.id = msgs.to_id
使用Laravel 函数DB::select 将查询结果提取到数组中。将上面的sql字符串放入一个变量$sql
$results_array = DB::select($sql)
了解 DB::select here。您还可以使用参数化查询。
和here是Laravel
中运行原始sql查询的一些示例我用下面的代码得到了预期的输出。 我知道我的代码有一些改进,但现在可以正常使用。
$user_id = $request->user_id;
$user_name = DB::table('users')->where('id', $user_id)->value('name');
$chats =DB::table('messages')
->leftJoin('users as u1', 'messages.from_id', '=', 'u1.id')
->leftJoin('users as u2', 'messages.to_id', '=', 'u2.id')
->select('u1.id as user_id', 'u1.name', 'u2.name as name2', 'messages.id','messages.from_id',
'messages.to_id', 'messages.body as message', 'messages.attachment', 'messages.created_at')
->where('messages.from_id', $user_id)
->orWhere('messages.to_id', $user_id)
->latest()
->get();
foreach($chats as $chat)
{
$chat->user_id = $chat->from_id == $user_id ? $chat->to_id : $chat->from_id;
$chat->name = $chat->name == $user_name ? $chat->name2 : $chat->name;
}
$chats = $chats->unique('user_id');