简体   繁体   中英

Select last row of each unique combination in SQL Server

I need to select last of row each unique combination, irrespective of the combination element order. For example combination (5,6) and (6,5) will be regarded as same combination.

Here is data on table: 在此处输入图片说明

My expected output:

在此处输入图片说明

What I have done so far:

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

And the output of my query is:

在此处输入图片说明

Any help from SQL Server experts?

You can use row_number() for this. The traditional method is:

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;

You can also phrase this without the subquery:

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
                           );

Try this:

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

The most inner query unifies senders and receivers, so their order is irrelevant:

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

The intermediate query assign row number to each row, so first is the latest date. Most outer query just filters based on that row number.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM