You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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=1
  • FIND_IN_SET('EMP001', READ) 是MySQL里判断值是否在逗号分隔字符串中的函数,其他数据库有对应替代:
    • SQL Server用CHARINDEX(',EMP001,', ',' + READ + ',') > 0
    • PostgreSQL用'EMP001' = ANY(string_to_array(READ, ','))

场景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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:32:01