我有一个表,用于存储带有正文的消息,从ID到ID以及发送日期时间:
ID | From | To | SendDate | Body
---------------------------------
1 10 20 [a date] blabla
2 20 10 [a date] some text
3 8 10 [a date] some more text
4 10 2 [a date] text
我想捕获用户10的所有“线程”, 但如果它们组合在一起并且仅返回最后一条消息(max senddate)
我不能比这更进一步:
select * from message where [to] = 10 or [From] = 10 order by senddate desc
这将为我提供用户10所涉及的所有消息,因此它将返回上面的确切表格, 但是记录1和2属于同一个“线程”(记录2是记录1上的回复),所以我需要将它们分组在一起,只返回最新记录(记录2)。
我想要的是:
ID | From | To | SendDate | Body
---------------------------------
2 20 10 [a date] some text
3 8 10 [a date] some more text
4 10 2 [a date] text
我该怎么做?
答案 0 :(得分:0)
如果要对用户10和20之间的所有邮件进行分组(不是吗?)...那么您可以“重新排序”From和To字段,以便于构建您的选择。
这是一个可行的解决方案:
SELECT BOTTOM, TOP, MAX("SendDate")
FROM
(SELECT CASE WHEN Message."To" < "From" THEN Message."To"
WHEN Message."To" > "From" THEN Message."From" END as Bottom,
CASE WHEN Message."To" > "From" THEN Message."To"
WHEN Message."To" < "From" THEN Message."From" END as Top,
Message."SendDate",
Message.Body
FROM
-- These sentences are only for simulate your TABLE
(select 2 as "ID", 10 as "From", 20 as "To", sysdate as "SendDate", 'Text' as Body from dual
union
select 3 as "ID", 20 as "From", 10 as "To", sysdate+1 as "SendDate", 'Text' as Body from dual
union
select 4 as "ID", 8 as "From", 10 as "To", sysdate as "SendDate", 'Text' as Body from dual) Messages)
GROUP BY BOTTOM, TOP;
答案 1 :(得分:0)
我有同样的任务,我的答案如下,
SELECT ID, From, To, SendDate, Body
FROM (
SELECT With, MAX(SendDate) as LatestDate
FROM (
SELECT
CASE WHEN message.From={{ id }} THEN message.To
WHEN message.To={{ id }} THEN message.From END AS With,
SendDate
FROM message
WHERE From={{ id }} OR To={{ id }}
)
GROUP BY With
) r
INNER JOIN message m ON (r.With = m.From OR r.With = m.To) AND r.LatestDate = m.SendDate
ORDER BY LatestDate DESC
关键是它一旦将{{id}}信息丢弃在最内部的子查询中。 通过这样做,它可以按线程分组。 之后,它再次调用select来加入除最新日期之外的数据。
问题是如果表中有相同的时间戳消息,则会选择两个线程,尽管它们代表相同的线程。 我认为这在实际情况下不会有问题,但应该更好地解决。
我认为这个答案并不完美,并且会有更有效的方法来解决这个问题。 如果有人知道更优雅的答案,请告诉我。