Выберите последнюю строку каждой уникальной комбинации в SQL Server - PullRequest
0 голосов
/ 27 августа 2018

Мне нужно выбрать последнюю строку в каждой уникальной комбинации, независимо от порядка элементов комбинации. Например, комбинация (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 голосов
/ 27 августа 2018

Попробуйте это:

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,

Промежуточному запросу присваивается номер строки для каждой строки, поэтому первая - самая последняя дата. Большинство внешних запросов просто фильтруются на основе этого номера строки.

0 голосов
/ 27 августа 2018

Вы можете использовать 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
                           );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...