0

我有一个看起来像这样的数据库表(我已经删除了不相关的字段)

[dbo].[UserMessage]
(
    [OwnerUserId] [int] NOT NULL,
    [FromUserId] [int] NOT NULL,
    [ToUserId] [int] NOT NULL,
    [CreationDateTime] [datetime2](7) NOT NULL
)

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

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 = 15 的所有对话,我希望返回的结果是

OwnerUserId    FromUserId    ToUserId    CreationDateTime
15             15            13          2013-06-26 14:09:38.1330000

如果我想要 OwnerUserId = 16 的所有对话,我希望返回的结果是

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 和新标识符进行分区,我可以将对话分组在一起。

4

0 回答 0