我有一个消息表,每个消息都属于一个唯一的对话(conversation_id)。我想从每个对话中选择最新消息。
下面的查询有效,但由于子查询选择了发送给用户的所有邮件,因此效率似乎非常低。
SELECT
conversation_id,
to_id,
from_id,
time_sent,
type,
message
FROM (
SELECT
*
FROM
messages
WHERE
to_id = :uid
OR
from_id = :uid
ORDER BY
time_sent
DESC
)
AS
t1
GROUP BY
conversation_id
ORDER BY
time_sent
DESC
如果我只包含GROUP BY
,则会选择第一行(最旧的)行:
SELECT
conversation_id,
to_id,
from_id,
time_sent,
type,
message
FROM
messages
WHERE
to_id = :uid
OR
from_id = :uid
GROUP BY
conversation_id
但是当我在同一个查询中执行GROUP BY
和ORDER BY
时,它会返回每个会话中的第一个(最旧的)行,而不是最后一个,因此ORDER BY
不是'工作或不做我期望的事。
SELECT
conversation_id,
to_id,
from_id,
time_sent,
type,
message
FROM
messages
WHERE
to_id = :uid
OR
from_id = :uid
GROUP BY
conversation_id
ORDER BY
time_sent
DESC
我非常确定我需要子查询,但是如何在不先选择所有邮件的情况下执行此操作?
答案 0 :(得分:2)
这可能是您寻找的方式
SELECT *
FROM messages
WHERE conversation_id = (
SELECT id
FROM conversations
WHERE id={insert id here...}
LIMIT 0,1)
ORDER BY id DESC
我假设您按会话ID选择。
答案 1 :(得分:2)
尝试将此表与每个对话的conversation_id
和max(time_sent)子查询结合起来:
SELECT
m.conversation_id,
m.to_id,
m.from_id,
m.time_sent,
m.type,
m.message
FROM messages as m
JOIN
(SELECT conversation_id,
MAX(time_sent) as MAX_time_sent
FROM messages
WHERE to_id = :uid OR from_id = :uid
GROUP BY conversation_id
) AS t1
ON m.conversation_id=t1.conversation_id AND m.time_sent = t1.MAX_time_sent
ORDER BY m.time_sent DESC
答案 2 :(得分:1)
这样的事情会这样做(假设to_id和from_id对话是一致的): -
SELECT messages.conversation_id,
messages.to_id,
messages.from_id,
messages.time_sent,
messages.type,
messages.message
FROM
(
SELECT conversation_id, MAX(time_sent) AS max_time_sent
FROM messages
GROUP BY conversation_id
) t1
INNER JOIN messages
ON t1.conversation_id = messages.conversation_id
AND t1.max_time_sent = messages.time_sent
WHERE messages.to_id = :uid
OR messages.from_id = :uid