SQL Server查询SELECT只有最新消息

时间:2016-01-26 02:51:27

标签: sql-server

 id|   from   | to      |message   |datetime             |
---| ---------|---------|----------|---------------------|
 1 | john     | peter   |Hi        |2016-01-01 12:00:00  |
 2 | peter    | john    |What's up |2016-01-01 12:01:00  |
 3 | jack     | jason   |Hey       |2016-01-02 12:00:00  |
 4 | jason    | jack    |Hi        |2016-01-01 12:01:00  |

让我们说我有一个这样的表,你们能不能给我一个如何编写SQL Server查询以仅选择两个用户之间的最新消息的想法。

上表的预期结果应该只选择id 2和3

2 个答案:

答案 0 :(得分:1)

使用ROW_NUMBER

WITH Cte AS(
    SELECT *,
        rn = ROW_NUMBER() OVER(
                            PARTITION BY 
                                CASE 
                                    WHEN [from] >= [to] THEN [from]
                                    ELSE [to]
                                END,
                                CASE 
                                    WHEN [from] >= [to] THEN [to]
                                    ELSE [from]
                                END
                            ORDER BY datetime DESC
                          )
    FROM tbl
)
SELECT * FROM CTE 
WHERE rn = 1
ORDER BY id

为了实现正确的分组,我按字母顺序排列PARTITION BY,这意味着PARTITION中的第一列将是按字母顺序从fromto开始的第一列,第二列将是最后一列。

Try it here.

答案 1 :(得分:1)

如果您不希望使用Felix的解决方案(使用SQL Server ROW_NUMBER),这是符合ANSI-92的解决方案:

SELECT m1.*
FROM messages m1
INNER JOIN
(
    SELECT t.v1 AS from, t.v2 AS to, MAX(t.datetime) AS maxTime
    FROM
    (
        SELECT CASE WHEN from < to THEN from ELSE to END AS v1,
               CASE WHEN from < to THEN to ELSE from END AS v2,
               datetime
        FROM messages
    ) t
    GROUP BY t.v1, t.v2
) m2
ON ((m1.from = m2.from AND m1.to = m2.to) OR (m1.from = m2.to AND m1.to = m2.from))
    AND m1.datetime = m2.maxTime