线程中的SQL组消息并获取最新消息

时间:2014-12-22 15:06:28

标签: sql tsql sql-server-2008-r2

我有一个表,用于存储带有正文的消息,从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

我该怎么做?

2 个答案:

答案 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来加入除最新日期之外的数据。

问题是如果表中有相同的时间戳消息,则会选择两个线程,尽管它们代表相同的线程。 我认为这在实际情况下不会有问题,但应该更好地解决。

我认为这个答案并不完美,并且会有更有效的方法来解决这个问题。 如果有人知道更优雅的答案,请告诉我。