SQL-通过对多个列进行分组来获取不同的、最新的行

SQL-通过对多个列进行分组来获取不同的、最新的行,sql,sql-server,database,select,group-by,Sql,Sql Server,Database,Select,Group By,我有一个类似这样的数据库表(我删除了不相关的字段) 在这个表中,我有以下数据 OwnerUserId FromUserId ToUserId CreationDateTime 13 13 15 2013-06-26 13:58:01.0270000 15 13 15 2013-06-26 13:58:24.0770000 13

我有一个类似这样的数据库表(我删除了不相关的字段)

在这个表中,我有以下数据

OwnerUserId    FromUserId    ToUserId    CreationDateTime   
13             13            15          2013-06-26 13:58:01.0270000
15             13            15          2013-06-26 13:58:24.0770000
13             15            13          2013-06-26 14:08:58.0070000
15             15            13          2013-06-26 14:08:43.8570000
13             13            15          2013-06-26 14:09:15.1030000
15             13            15          2013-06-26 14:09:26.2000000
13             15            13          2013-06-26 14:09:47.0030000
15             15            13          2013-06-26 14:09:38.1330000
13             13            16          2013-06-26 14:20:27.5170000
16             13            16          2013-06-26 14:20:41.0130000
我想要的是一个sql查询,它为不同用户之间的粒子所有者返回最新的不同消息。 因此,如果我想要OwnerUserId=13的所有对话,我希望返回的结果是

OwnerUserId    FromUserId    ToUserId    CreationDateTime
13             13            16          2013-06-26 14:20:27.5170000
13             15            13          2013-06-26 14:09:47.0030000
OwnerUserId    FromUserId    ToUserId    CreationDateTime
15             15            13          2013-06-26 14:09:38.1330000
OwnerUserId    FromUserId    ToUserId    CreationDateTime
16             13            16          2013-06-26 14:20:41.0130000
如果我想要OwnerUserId=15的所有对话,我希望返回的结果是

OwnerUserId    FromUserId    ToUserId    CreationDateTime
13             13            16          2013-06-26 14:20:27.5170000
13             15            13          2013-06-26 14:09:47.0030000
OwnerUserId    FromUserId    ToUserId    CreationDateTime
15             15            13          2013-06-26 14:09:38.1330000
OwnerUserId    FromUserId    ToUserId    CreationDateTime
16             13            16          2013-06-26 14:20:41.0130000
如果我想要OwnerUserId=16的所有对话,我希望返回的结果是

OwnerUserId    FromUserId    ToUserId    CreationDateTime
13             13            16          2013-06-26 14:20:27.5170000
13             15            13          2013-06-26 14:09:47.0030000
OwnerUserId    FromUserId    ToUserId    CreationDateTime
15             15            13          2013-06-26 14:09:38.1330000
OwnerUserId    FromUserId    ToUserId    CreationDateTime
16             13            16          2013-06-26 14:20:41.0130000
我已经为[OwnerUserId]=13创建了一个如下的查询

WITH cte AS
(
   SELECT *, ROW_NUMBER() OVER (PARTITION BY OwnerUserId, fromUserId, ToUserId ORDER BY CreationDateTime DESC) AS rn
   FROM [UserMessage]
)
SELECT *
FROM cte
WHERE rn = 1
and [OwnerUserId] = 13;
但是这个查询返回

OwnerUserId    FromUserId    ToUserId    CreationDateTime               rn
13             13            15          2013-06-26 14:09:15.1030000    1
13             13            16          2013-06-26 14:20:27.5170000    1
13             15            13          2013-06-26 14:09:47.0030000    1
我不希望返回最上面的一行,因为最后一行已经表示了相同的对话(尽管FromUserID和ToUserId是反向的)。 有什么想法吗? 该解决方案应该适用于任何[OwnerUserId](我使用了13作为示例)

!!!!!!!!!!!!!!!!回答

WITH cte AS
(
   SELECT *, 
   ROW_NUMBER() OVER 
   (
       PARTITION BY OwnerUserId, 
       CHECKSUM(CASE WHEN ToUserId > fromUserId THEN (convert(varchar(256),ToUserId) + ':' + convert(varchar(256),fromUserId)) ELSE (convert(varchar(256),fromUserId) + ':' + convert(varchar(256),ToUserId)) END) 
       ORDER BY CreationDateTime desc
    ) AS rn
    FROM [UserMessage]
)
SELECT *
FROM cte
WHERE rn = 1
and [OwnerUserId] = 13;
我通过在查询的分区中使用校验和得到了解决方案。
基本上,我将fromUserId和toUserId结合起来,为对话创建一个唯一的标识符。通过对OwnerUserId和新标识进行分区,我可以将对话分组。

如果
[OwnerUserId]=16
,结果应该是什么?OwnerUserId=16的结果应该是16,13,162013-06-26 14:20:41.0130000。只有一行OwnerUserId=15的结果应该是一行15,15,132013-06-26 14:09:38.1330000。那么您的意思是第15,13,15,2013-06-26 14:09:26.000行不应该出现在结果中?如果[OwnerUserId]=16,那么第15,13,15,2013-06-26 14:09:26.000行不应该出现在结果中。