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

如何简化按月汇总部门faltas的Oracle SQL查询?

更简洁的Oracle SQL实现方案

针对你用多次UNION ALL重复代码来汇总部门近N个月faltas并生成合计报表的问题,可以通过以下几种简洁写法实现相同效果,大幅降低维护成本:

方案1:条件聚合+ROLLUP(月份作为列展示)

如果需要把每个月份作为单独的列、部门作为行,同时自动生成"Total Geral"汇总行,用这种写法:

SELECT 
    CASE WHEN GROUPING(dept) = 1 THEN 'Total Geral' ELSE dept END AS departamento,
    -- 近3个月的统计,13个月的话只需修改ADD_MONTHS的偏移量为-12
    SUM(CASE WHEN TRUNC(data, 'MM') = ADD_MONTHS(TRUNC(SYSDATE, 'MM'), -2) THEN faltas ELSE 0 END) AS mes_3,
    SUM(CASE WHEN TRUNC(data, 'MM') = ADD_MONTHS(TRUNC(SYSDATE, 'MM'), -1) THEN faltas ELSE 0 END) AS mes_2,
    SUM(CASE WHEN TRUNC(data, 'MM') = TRUNC(SYSDATE, 'MM') THEN faltas ELSE 0 END) AS mes_1,
    SUM(faltas) AS total_por_departamento
FROM sua_tabela
-- 过滤近3个月数据,13个月则改成ADD_MONTHS(TRUNC(SYSDATE, 'MM'), -12)
WHERE data BETWEEN ADD_MONTHS(TRUNC(SYSDATE, 'MM'), -2) AND LAST_DAY(TRUNC(SYSDATE, 'MM'))
GROUP BY ROLLUP(dept);

优势:

  • 只需要写一次主查询逻辑,修改月份范围仅需调整ADD_MONTHS的偏移参数
  • ROLLUP自动生成全局汇总行,无需额外写UNION ALL拼接合计

方案2:GROUPING SETS(月份作为行展示)

如果报表需要每个部门每个月一行,最后追加全局合计,用GROUPING SETS替代多次UNION ALL:

SELECT 
    CASE WHEN GROUPING(dept) = 1 THEN 'Total Geral' ELSE dept END AS departamento,
    CASE WHEN GROUPING(TO_CHAR(data, 'YYYY-MM')) = 1 THEN 'Todos os meses' ELSE TO_CHAR(data, 'YYYY-MM') END AS mes,
    SUM(faltas) AS total_faltas
FROM sua_tabela
WHERE data BETWEEN ADD_MONTHS(TRUNC(SYSDATE, 'MM'), -2) AND LAST_DAY(TRUNC(SYSDATE, 'MM'))
-- 指定分组组合:(部门+月份)的明细、全局合计
GROUP BY GROUPING SETS ((dept, TO_CHAR(data, 'YYYY-MM')), ());

优势:

  • 一次分组即可同时生成明细行和合计行,完全避免重复代码
  • 扩展月份范围只需修改WHERE条件中的日期偏移

方案3:CTE+单次UNION ALL(兼容旧版本Oracle)

如果使用的Oracle版本不支持GROUPING SETS/ROLLUP(10g及以前),可以用CTE先统计明细,再追加合计:

WITH dados_mensais AS (
    SELECT 
        dept AS departamento,
        TO_CHAR(data, 'YYYY-MM') AS mes,
        SUM(faltas) AS total_faltas
    FROM sua_tabela
    WHERE data BETWEEN ADD_MONTHS(TRUNC(SYSDATE, 'MM'), -2) AND LAST_DAY(TRUNC(SYSDATE, 'MM'))
    GROUP BY dept, TO_CHAR(data, 'YYYY-MM')
)
SELECT departamento, mes, total_faltas FROM dados_mensais
UNION ALL
SELECT 'Total Geral', 'Todos os meses', SUM(total_faltas) FROM dados_mensais
ORDER BY departamento, mes;

优势:

  • 明细逻辑只写一次,合计直接复用CTE结果,比多次UNION ALL简洁得多

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 07:47:35