MySQL/MariaDB10.1 如何先ORDER BY再GROUP BY?业务场景求助
解决方案
首先,考虑到你提到的THREAD筛选规则没完全说明,我先基于几种常见的业务场景给出对应的SQL示例,你可以根据实际需求调整:
场景1:选取每个工单对应的最新THREAD记录,且该记录未被指定员工读取
假设我们要筛选每个工单的最新THREAD(按ID降序取第一条),并且这条THREAD的已读列表里不包含员工ID 'EMP001':
SELECT t.TITLE FROM TICKET t JOIN ( SELECT THREAD.*, ROW_NUMBER() OVER (PARTITION BY TICKET_ID ORDER BY ID DESC) AS rn FROM THREAD WHERE NOT FIND_IN_SET('EMP001', READ) -- 判断员工ID不在已读列表中 ) th ON t.TICKET_ID = th.TICKET_ID WHERE th.rn = 1;
说明:
ROW_NUMBER() OVER (PARTITION BY TICKET_ID ORDER BY ID DESC)用来给每个工单下的THREAD记录排序,最新的那条会被标记为rn=1FIND_IN_SET('EMP001', READ)是MySQL里判断值是否在逗号分隔字符串中的函数,其他数据库有对应替代:- SQL Server用
CHARINDEX(',EMP001,', ',' + READ + ',') > 0 - PostgreSQL用
'EMP001' = ANY(string_to_array(READ, ','))
- SQL Server用
场景2:选取每个工单对应特定TYPE的THREAD记录,且该记录无人读取
如果需要筛选TYPE为'NOTICE'的THREAD,且这条记录的已读列表为空:
SELECT t.TITLE FROM TICKET t JOIN ( SELECT THREAD.*, ROW_NUMBER() OVER (PARTITION BY TICKET_ID ORDER BY ID DESC) AS rn FROM THREAD WHERE TYPE = 'NOTICE' AND READ IS NULL ) th ON t.TICKET_ID = th.TICKET_ID WHERE th.rn = 1;
核心思路
用窗口函数ROW_NUMBER()可以精准控制每个工单只返回一条符合条件的THREAD记录,你可以根据实际需求调整ORDER BY的字段(比如按创建时间排序,如果表中有这个字段的话)。如果你的筛选规则和上面场景不同,可以补充具体规则,我再帮你优化SQL语句。
内容的提问来源于stack exchange,提问作者Rcwd
相关产品推荐
相关产品推荐

