sql查询通过对话分组数据

Zel*_*Ady 1 sql t-sql sql-server

我需要这个任务的帮助:我在MsSql数据库中有一个表,我存储了用户间的消息.我需要一个查询来为每个用户对话选择最后一条消息(WhatApp类似于用户的对话列表).

表结构(x是消息ID,GUID,对于每条消息都是唯一的,txtMsg是文本消息):

| messageId | fromUserId | toUserId | Message |     sentDate     |
|     x     |      1     |     2    |  txtMsg | 1.1.2016 1:00:00 |
|     x     |      1     |     2    |  txtMsg | 1.1.2016 1:00:01 |
|     x     |      1     |     2    |  txtMsg | 1.1.2016 1:00:02 |
|     x     |      2     |     1    |  txtMsg | 1.1.2016 1:00:03 |
|     x     |      3     |     1    |  txtMsg | 1.1.2016 1:00:04 |
|     x     |      4     |     1    |  txtMsg | 1.1.2016 1:00:05 |
|     x     |      2     |     3    |  txtMsg | 1.1.2016 1:00:06 |
|     x     |      2     |     4    |  txtMsg | 1.1.2016 1:00:07 |
|     x     |      2     |     3    |  txtMsg | 1.1.2016 1:00:08 |
|     x     |      1     |     5    |  txtMsg | 1.1.2016 1:00:09 |
|     x     |      3     |     1    |  txtMsg | 1.1.2016 1:00:10 |
|     x     |      2     |     4    |  txtMsg | 1.1.2016 1:00:11 |
|     x     |      2     |     5    |  txtMsg | 1.1.2016 1:00:12 |
|     x     |      1     |     2    |  txtMsg | 1.1.2016 1:00:13 |
Run Code Online (Sandbox Code Playgroud)

预期结果示例,对于id = 1的用户(sentDate是最新日期):

|     x     |      1     |     2    |  txtMsg | 1.1.2016 1:00:13 |
|     x     |      3     |     1    |  txtMsg | 1.1.2016 1:00:10 |
|     x     |      4     |     1    |  txtMsg | 1.1.2016 1:00:05 |
|     x     |      1     |     5    |  txtMsg | 1.1.2016 1:00:09 |
Run Code Online (Sandbox Code Playgroud)

什么SQL查询会创建这样的结果?

谢谢!

稍后编辑:我在这里添加了sqlfiddle示例:

http://sqlfiddle.com/#!3/6ffbe/15

Gor*_*off 5

您可以使用row_nubmer大小写逻辑来获取最小和最大的用户ID:

select m.*
from (select m.*,
             row_number() over (partition by  (case when fromuserid < touserid then fromuserid else touserid end),
                                              (case when fromuserid < touserid then touserid else fromuserid end)
                                order by sentDate desc
                               ) as seqnum
      from messages m
     ) m
where seqnum = 1;
Run Code Online (Sandbox Code Playgroud)

编辑:

这个SQL适用于SQL Fiddle:

select m.*
from (select m.*,
             row_number() over (partition by  (case when fromuser < touser then fromuser else touser end),
                                              (case when fromuser < touser then touser else fromuser end)
                                order by createdAt desc
                               ) as seqnum
      from messages m
     ) m
where seqnum = 1;
Run Code Online (Sandbox Code Playgroud)