SQL查询求助:从单表获取每组ToNum/FromNum配对的最新唯一记录
解决方案:获取MSSQL中每组双向通信的最新记录
原始表数据
| ID | Type | ToNum | FromNum | sDate | Msg |
|---|---|---|---|---|---|
| 1 | 1 | 6025551212 | 6235551234 | 2022-11-05 13:44:00 | This is a test |
| 2 | 1 | 4805554321 | 6235551234 | 2022-11-05 13:50:00 | Test message |
| 3 | 2 | 6235551234 | 4805554321 | 2022-11-05 13:51:00 | Response to your message |
| 4 | 1 | 4805554321 | 6235551234 | 2022-11-05 14:01:00 | Got your response! |
| 5 | 1 | 4805557891 | 6235551234 | 2022-11-05 14:02:00 | Test to -7891 |
| 6 | 2 | 6235551234 | 4805557891 | 2022-11-05 14:04:00 | Hi! Thanks. |
期望结果
| ID | Type | ToNum | FromNum | sDate | Msg |
|---|---|---|---|---|---|
| 1 | 1 | 6025551212 | 6235551234 | 2022-11-05 13:44:00 | This is a test |
| 4 | 1 | 4805554321 | 6235551234 | 2022-11-05 14:01:00 | Got your response! |
| 6 | 2 | 6235551234 | 4805557891 | 2022-11-05 14:04:00 | Hi! Thanks. |
实现SQL语句
核心思路是将ToNum和FromNum视为双向对话组(即A→B和B→A属于同一组),通过窗口函数为每组按时间倒序分配行号,最终筛选出行号为1的最新记录:
WITH RankedMessages AS ( SELECT *, -- 生成统一的对话组标识:将两个号码按字典序排序后作为分组依据 ROW_NUMBER() OVER ( PARTITION BY CASE WHEN ToNum < FromNum THEN ToNum ELSE FromNum END, CASE WHEN ToNum < FromNum THEN FromNum ELSE ToNum END ORDER BY sDate DESC ) AS rn FROM YourTableName -- 替换为你的实际表名 ) SELECT ID, Type, ToNum, FromNum, sDate, Msg FROM RankedMessages WHERE rn = 1;
语句说明
- CTE部分:通过
CASE表达式将每对号码按固定顺序排序,确保A→B和B→A被分到同一个分组中;然后用ROW_NUMBER()为每组内的记录按sDate降序编号,最新的记录行号为1。 - 筛选部分:直接选取行号为1的记录,即为每组对话的最新消息。
内容的提问来源于stack exchange,提问作者bdiz
相关产品推荐
相关产品推荐

