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

Oracle:根据选定年份查询12条月度汇总数据的SQL实现

解决方案

假设你的表名为MONTHLY_STATS,可以使用以下SQL实现需求,通过绑定变量:p_selected_year传入你要查询的年份:

SELECT ID, Month, Year, "Sum of objects"
FROM MONTHLY_STATS
WHERE
  -- 场景1:查询过去年份,返回该年全部12个月数据
  (:p_selected_year <> EXTRACT(YEAR FROM SYSDATE)
   AND Year = :p_selected_year
   AND Month BETWEEN 1 AND 12)
  OR
  -- 场景2:查询当前年份,返回今年已过月份 + 去年剩余月份凑足12条
  (:p_selected_year = EXTRACT(YEAR FROM SYSDATE)
   AND (
       -- 当前年的1到当前月份
       (Year = :p_selected_year AND Month <= EXTRACT(MONTH FROM SYSDATE))
       OR
       -- 去年的(当前月份+1)到12月份
       (Year = :p_selected_year - 1 AND Month > EXTRACT(MONTH FROM SYSDATE))
   ))
-- 按时间顺序排序,确保结果从早到晚排列
ORDER BY Year, Month;

为什么你的之前尝试失败?

Oracle的CASE表达式无法直接返回布尔条件(比如BETWEEN...AND),它只能返回具体值,所以你之前在WHERE里用CASE的写法会导致语法或逻辑错误。改用逻辑分支(OR)拆分两种场景,就能清晰实现需求。

补充说明

  • 如果你的Month列是字符串类型(比如'01'、'02'),需要先转换成数字类型再比较,比如TO_NUMBER(Month)。
  • 如果某些月份没有统计数据(表中无对应记录),需要返回Sum of objects为0的行,可以用CONNECT BY生成12个目标月份,再与表做左连接,示例如下:
WITH target_months AS (
  SELECT
    CASE
      WHEN :p_selected_year = EXTRACT(YEAR FROM SYSDATE) THEN
        CASE WHEN rn <= EXTRACT(MONTH FROM SYSDATE) THEN :p_selected_year ELSE :p_selected_year -1 END
      ELSE :p_selected_year
    END AS target_year,
    CASE
      WHEN :p_selected_year = EXTRACT(YEAR FROM SYSDATE) THEN
        CASE WHEN rn <= EXTRACT(MONTH FROM SYSDATE) THEN rn ELSE rn - EXTRACT(MONTH FROM SYSDATE) END
      ELSE rn
    END AS target_month
  FROM (SELECT ROWNUM rn FROM DUAL CONNECT BY ROWNUM <=12)
)
SELECT
  tm.target_year AS Year,
  tm.target_month AS Month,
  NVL(ms."Sum of objects", 0) AS "Sum of objects"
FROM target_months tm
LEFT JOIN MONTHLY_STATS ms
  ON ms.Year = tm.target_year AND ms.Month = tm.target_month
ORDER BY tm.target_year, tm.target_month;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 23:47:07