如何对MessageTable短信表按联系人分组后按日期时间交叉排序
问题描述
我现有一张名为MessageTable的短信表,存储了用户Ali的手机短信收发记录,包含Ali接收他人短信和向他人发送的回复短信,表结构和数据如下:
| id | sendDate | sendTime | sender | receiver |
|---|---|---|---|---|
| 1 | 1397/01/02 | 10:02 | Karim | Ali |
| 2 | 1398/05/09 | 05:30 | Hamed | Ali |
| 3 | 1398/06/07 | 05:10 | Majid | Ali |
| 4 | 1398/08/09 | 06:12 | Ali | Karim |
| 5 | 1399/02/01 | 07:15 | Ali | Saeed |
| 6 | 1399/07/02 | 08:51 | Parsa | Ali |
| 7 | 1399/08/06 | 12:20 | Ali | Karim |
| 8 | 1399/09/04 | 20:01 | Ali | Hamed |
| 9 | 1399/12/08 | 22:05 | Asgar | Ali |
| 10 | 1400/01/01 | 23:11 | Majid | Ali |
| 11 | 1400/02/13 | 14:10 | Karim | Ali |
| 12 | 1400/04/05 | 16:25 | Ali | Hamed |
| 12 | 1400/06/12 | 22:25 | Ali | Majid |
| 12 | 1400/07/24 | 08:25 | Saeed | Ali |
需要对该表进行排序,满足以下要求:首先将Ali与每位联系人的所有往来短信单独归为一组排列,其次每组内的短信按发送日期和时间升序排列,预期排序效果如下:
| id | sendDate | sendTime | sender | receiver |
|---|---|---|---|---|
| 1 | 1397/01/02 | 10:02 | Karim | Ali |
| 4 | 1398/08/09 | 06:12 | Ali | Karim |
| 7 | 1399/08/06 | 12:20 | Ali | Karim |
| 11 | 1400/02/13 | 14:10 | Karim | Ali |
| 2 | 1398/05/09 | 05:30 | Hamed | Ali |
| 8 | 1399/09/04 | 20:01 | Ali | Hamed |
| 12 | 1400/04/05 | 16:25 | Ali | Hamed |
| 3 | 1398/06/07 | 05:10 | Majid | Ali |
| 10 | 1400/01/01 | 23:11 | Majid | Ali |
| 12 | 1400/06/12 | 22:25 | Ali | Majid |
| 5 | 1399/02/01 | 07:15 | Ali | Saeed |
| 12 | 1400/07/24 | 08:25 | Saeed | Ali |
| 6 | 1399/07/02 | 08:51 | Parsa | Ali |
| 9 | 1399/12/08 | 22:05 | Asgar | Ali |
请问如何编写对应的SQL代码实现上述排序需求?
解决方案
核心思路是先提取每条短信对应的联系人(即sender和receiver中不是Ali的那一方),先按联系人排序实现同组聚集,再按发送日期和时间升序排列组内内容,对应SQL代码如下:
SELECT * FROM MessageTable ORDER BY -- 提取往来联系人,按联系人分组排序 CASE WHEN sender = 'Ali' THEN receiver ELSE sender END, -- 组内按发送时间升序排列 sendDate ASC, sendTime ASC;
说明
- CASE判断逻辑会自动识别每条记录对应的联系人:如果Ali是发送方,取接收方为联系人;如果Ali是接收方,取发送方为联系人,保证同一位联系人的所有往来短信会被归为同一组
- 如果你的数据库中sendDate为字符串类型无法直接按日期逻辑排序,可以先通过日期转换函数处理,例如MySQL可以用
STR_TO_DATE(sendDate, '%Y/%m/%d')替换排序条件中的sendDate,避免字符串排序出错。
内容的提问来源于stack exchange,提问作者honey bee
相关产品推荐
相关产品推荐

