首先,非常感谢您的帮助。
我有2个表:conversation
表和message
表,以及将消息与对话相关联的第三个表assoc_message__conversation
。
我需要获取针对指定的每个会话发送的最新message_id
和message
,以及与之相关的conversation_id
。
这是一个分贝小提琴:https://www.db-fiddle.com/f/kxRQeGUYYgQ7FTwi96hbLp/0
如本例所示,有conversation_id
为1和2的两个对话,并且每个对话有3条消息。消息1、2和3与会话1相关联,消息4、5和6与会话2相关联。
我需要能够在conversation_id
表(ID 1和2)中指定assoc_message__conversation
,并检索最新的message_id
,message
和从conversation_id
表发送的与指定的每次会话相关联的message
。
所以它应该拉的行是:
conversation_id | message_id | message
------------------------------------------------
1 | 3 | "Latest message"
------------------------------------------------
2 | 6 | "Latest message"
------------------------------------------------
非常感谢您的帮助!
答案 0 :(得分:1)
在旧版的MySQL(<8.0.2)中,我们可以使用Derived Tables。在派生表中,我们可以获取每个send_datetime
的最新conversation_id
值。 此外,值得注意的是,您可以在此子查询的WHERE
子句中为session_id提供过滤器。
然后我们可以使用该子查询的结果集,并适当地返回主表,以获取与会话中最新消息相对应的行。
模式(MySQL v5.7)
查询#1
SELECT
amc.conversation_id,
m.message_id,
m.message
FROM
assoc_message__conversation AS amc
JOIN message AS m
ON m.message_id = amc.message_id
JOIN
(
SELECT
amc1.conversation_id,
MAX(m1.send_datetime) AS latest_send_datetime
FROM
assoc_message__conversation AS amc1
JOIN message AS m1
ON m1.message_id = amc1.message_id
WHERE amc1.conversation_id IN (1,2) -- Here you provide your input filters
GROUP BY amc1.conversation_id
) AS dt
ON dt.conversation_id = amc.conversation_id AND
dt.latest_send_datetime = m.send_datetime;
结果
| conversation_id | message_id | message |
| --------------- | ---------- | -------------- |
| 1 | 3 | Latest message |
| 2 | 6 | Latest message |
在MySQL 8.0.2及更高版本中,我们可以使用Row_Number()
功能。在conversation_id
的分区中,我们将确定每个消息的行号,并按send_datetime
的降序排列。 在此子查询中,您可以在WHERE
子句中提供针对session_id的过滤器。
然后,我们将此结果集用作派生表,并仅考虑行号值为1的那些行(因为它将属于最新的send_datetime
)。
模式(MySQL v8.0)
查询#2
SELECT
dt.conversation_id,
dt.message_id,
dt.message
FROM
(
SELECT
amc.conversation_id,
m.message_id,
m.message,
ROW_NUMBER() OVER (PARTITION BY amc.conversation_id
ORDER BY m.send_datetime DESC) AS row_no
FROM
assoc_message__conversation AS amc
JOIN message AS m
ON m.message_id = amc.message_id
WHERE amc.conversation_id IN (1,2) -- Here you provide your input filters
) AS dt
WHERE dt.row_no = 1;
结果
| conversation_id | message_id | message |
| --------------- | ---------- | -------------- |
| 1 | 3 | Latest message |
| 2 | 6 | Latest message |
答案 1 :(得分:0)
假设每条新消息增加amc_id
,我将在where
子句中建议一个相关的子查询:
select amc.*, m.message
from message m join
assoc_message__conversation amc
on amc.message_id = m.message_id
where amc.amc_id = (select max(amc.amc_id)
from assoc_message__conversation amc2
where amc2.conversation_id = amc.conversation_id
);
如果您实际上需要使用send_datetime
,则需要另外使用join
:
where m.send_datetime = (select max(m2.send_datetime)
from message m2 join
assoc_message__conversation amc2
on amc2.message_id = m2.message_id
where amc2.conversation_id = amc.conversation_id
)