选择SQL Server中每个唯一组合的最后一行

时间:2018-08-27 12:00:04

标签: sql sql-server tsql

无论组合元素的顺序如何,我都需要选择每个唯一组合的最后一行。例如,组合(5,6)(6,5)将被视为同一组合。

以下是表中的数据: enter image description here

我的预期输出:

enter image description here

我到目前为止所做的事情:

Select * From
(
Select *, ROW_NUMBER() over (Partition by SenderId, ReceiverId order by MessageId desc) as Seq From Messages
) as TempTalbe Where Seq = 1

我的查询输出为:

enter image description here

SQL Server专家有什么帮助吗?

2 个答案:

答案 0 :(得分:2)

您可以为此使用row_number()。传统方法是:

select m.*
from (select m.*,
             row_number() over (partition by (case when senderId < receiverId then senderId else receiverId end),
                                             (case when senderId < receiverId then receiverId else senderId end)
                                order by messageSentAt desc
                               ) as seqnum
      from messages m
     ) m
where seqnum = 1;

您也可以在不使用子查询的情况下对此进行措辞:

select top (1) with ties m.*
from messages m
order by row_number() over (partition by (case when senderId < receiverId then senderId else receiverId end),
                                         (case when senderId < receiverId then receiverId else senderId end)
                            order by messageSentAt desc
                           );

答案 1 :(得分:1)

尝试一下:

select messageId,
       messageBody,
       messageSentAt,
       isRead
from (
    select messageId,
           messageBody,
           messageSentAt,
           isRead,
           row_number() over (partition by senderId, receiverId order by messageSentAt desc) rn
    from (
        select messageId,
               case when senderId > receiverId then senderId else receiverId end senderId,
               case when senderId < receiverId then senderId else receiverId end receiverId,
               messageBody,
               messageSentAt,
               isRead
        from Messages
    ) a
) a where rn = 1

最内部的查询统一了发送者和接收者,因此它们的顺序无关紧要:

case when senderId > receiverId then senderId else receiverId end senderId,
case when senderId < receiverId then senderId else receiverId end receiverId,

中间查询为每行分配行号,因此第一个是最新日期。大多数外部查询只是根据该行号进行过滤。