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
答案 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
中的第一列将是按字母顺序从from
和to
开始的第一列,第二列将是最后一列。
答案 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