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

如何编写SQL查询:按Report_number分组,无编号则保留全记录

优化SQL查询方案:分组有编号报告+全列无编号报告

方案1:用窗口函数(首推,性能更好)

用ROW_NUMBER()窗口函数就能一次搞定,不用拆成两个查询再UNION,效率更高。核心思路是:给每个有编号的报告组编行号,只留每组第一行;无编号的报告单独成组,自然全部保留。

举个实际例子(假设表名叫reports,字段有id, content, report_number, create_time,要取每组最新的报告):

SELECT id, content, report_number, create_time
FROM (
    SELECT 
        id, content, report_number, create_time,
        -- 有编号的按编号分组,无编号的按自己id分组(保证每条都是单独一组)
        -- 每组按创建时间倒序,行号1就是最新的那条
        ROW_NUMBER() OVER (
            PARTITION BY CASE WHEN report_number IS NOT NULL THEN report_number ELSE id END 
            ORDER BY create_time DESC
        ) AS rn
    FROM reports
) t
WHERE rn = 1;

要是你不想取最新的,把ORDER BY create_time DESC改成ASC就能取最早的,或者按其他字段排序都行。

方案2:聚合函数+UNION ALL(兼容老版本数据库)

如果你的数据库不支持窗口函数(比如老版MySQL),可以用这个备选方案。注意用UNION ALL代替UNION,因为不用做去重,速度更快:

-- 先取有编号的每组一条(这里拿id最大的记录当代表)
SELECT MAX(id) AS id, MAX(content) AS content, report_number, MAX(create_time) AS create_time
FROM reports
WHERE report_number IS NOT NULL
GROUP BY report_number
UNION ALL
-- 再取所有无编号的记录
SELECT id, content, report_number, create_time
FROM reports
WHERE report_number IS NULL;

聚合函数选MAX还是MIN,根据你要保留哪条记录来定。

为啥比原来的UNION好?

  • 窗口函数方案只需要扫一次表,大数据量下性能碾压两次扫描的UNION方案
  • 就算用UNION ALL的备选,也比原来的UNION快,因为少了去重的开销

内容的提问来源于stack exchange,提问作者qed59

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 10:45:58