简体   繁体   English

返回子查询中的最后一条记录 - MySQL

[英]Returning last record in a subquery - MySQL

So I am creating a messaging system similar to Facebook's style for my website (I know right).所以我正在为我的网站创建一个类似于 Facebook 风格的消息传递系统(我知道是对的)。 What I intend to happen is list all conversations for the user and also return the last message in the conversation.我打算发生的是列出用户的所有对话,并返回对话中的最后一条消息。 Problem is I am getting the first message when doing a GROUP BY.问题是我在执行 GROUP BY 时收到第一条消息。 Perhaps I am going about it in the wrong way.也许我以错误的方式去做这件事。

The structure of the database consists of three tables.数据库的结构由三个表组成。 conversations , conversations_assign , conversations_msg对话对话_分配对话_msg

conversations just stores the outside data of the conversation and the important thing is the id对话只存储对话的外部数据,重要的是id

conversations_assign does just that.对话分配就是这样做的。 It lists the userid of everyone in the conversation它列出了对话中每个人的用户名

conversations_msg stores obviously the message, user who posted with other data. sessions_msg显然存储了消息,与其他数据一起发布的用户。

Everything is tied together with conversations.id = conv_id一切都与conversations.id = conv_id联系在一起

Here is the query I have and as I said from above with GROUP BY it is returning the first result.这是我的查询,正如我上面所说的 GROUP BY 它返回第一个结果。 Taking off GROUP BY and adding LIMIT 1 literally returns one message and the rest are null.取消 GROUP BY 并添加 LIMIT 1 字面上返回一条消息,其余消息为空。 Any help is appreciated, thanks!任何帮助表示赞赏,谢谢!

SELECT conversations.id,
    conversations_assign.num_unread,
    message
FROM conversations_assign
INNER JOIN conversations ON conversations_assign.conv_id=conversations.id                                     
LEFT JOIN (
    SELECT conv_id, message, msg_time
    FROM conversations_msg
    GROUP BY conv_id
) AS message ON message.conv_id=conversations_assign.conv_id
WHERE conversations_assign.userid='XXsomeidXX'
ORDER BY message.msg_time DESC

You can't do what you want with aggregation.你不能用聚合做你想做的事。 Instead, you need to filter .相反,您需要过滤. If you are running MySQL 8.0, I would recommend window functions:如果您运行的是 MySQL 8.0,我会推荐窗口函数:

select c.id, ca.num_unread, cm.message
from conversations_assign c
inner join conversations ca on ca.conv_id =c.id                                     
left join (
    select cm.*, rank() over(partition by conv_id order by msg_time desc) rn
    from conversations_msg cm
) as cm on cm.conv_id = ca.conv_id and cm.rn = 1
where ca.userid = 'xxsomeidxx'
order by cm.msg_time desc

In earlier versions, an alternative uses a correlated subquery to filter the left join :在早期版本中,替代方法使用相关子查询来过滤left join

select c.id, ca.num_unread, cm.message
from conversations_assign c
inner join conversations ca 
    on  ca.conv_id =c.id                                     
left join conversations_msg cm
    on  cm.conv_id = ca.conv_id 
    and cm.msg_time = (
        select max(cm1.msg_time) from conversations_msg cm1 where cm1.conv_id = ca.conv_id
    )
where ca.userid = 'xxsomeidxx'
order by cm.msg_time desc

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM