SQL对线程中的消息进行分组并获取最新消息

SQL对线程中的消息进行分组并获取最新消息,sql,tsql,sql-server-2008-r2,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]

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

如何才能做到这一点?

如果您想将用户10和20之间的所有消息分组,不是吗?…那么您可以对“发件人”和“收件人”字段重新排序,以便于构建选择

这是一个可行的解决方案:

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;

我有同样的任务,我的回答如下:

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

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

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

你怎么知道记录2是对记录1的答复?它可能是一条新消息,而不是对第一条消息的响应。我想在对话中分组,所以它总是一个回复或一个对话开始