如何使用案例在同一行中按月、季度和年份对销售额进行分组?

How to group sales by month, quarter and year in the same row using case?

我正在尝试 return 2016 年 year 每个 month、每个 quartersales 总数。我想要在第一行 month 显示年销售额,而不是在其他行。另外,我想在每个 quarter 的第一个 month 上显示 quarter 销售额,而不是在其他

上显示

为了进一步解释这一点,这是我想要实现的目标:

MONTH   MONTH_SALES QUARTER_SALES   YEAR_SALES
  1         2183        5917          12505
  2         1712         -              - 
  3         1972         -              - 
  4         2230        6588            - 
  5         2250         -              - 
  6         2108         -              -

到目前为止,这是我的 SQL 查询:

SELECT
    Time.month,
    SUM(Sales.sales) AS MONTH_SALES, -- display monthly sales.
    CASE
        WHEN MOD(Time.month, 3) = 1 THEN ( -- first month of quarter
            SELECT
                SUM(Sales.sales)
            FROM
                Sales,
                Time
            WHERE
                Sales.Time_id = Time.Time_id
                AND Time.year = 2016
            GROUP BY
                Time.quarter
            FETCH FIRST 1 ROW ONLY
        )
    END AS QUARTER_SALES,
    CASE
        WHEN Time.month = 1 THEN ( -- display annual sales.
            SELECT
                SUM(Sales.sales)
            FROM
                Sales,
                Time
            WHERE
                Sales.Time_id = Time.Time_id
                AND Time.year = 2016
            GROUP BY
                Time.year
        )
    END AS YEAR_SALES
FROM
    Sales,
    Time
WHERE
    Sales.Time_id = Time.Time_id
    AND Time.year = 2016
GROUP BY
    Time.month
ORDER BY
    Time.month

我几乎得到了想要的输出,但我在第一个月和第四个月的季度销售额中得到了相同的重复值 6588(因为我正在获取第一季度的第一行)。

MONTH   MONTH_SALES QUARTER_SALES   YEAR_SALES
  1         2183        6588          12505
  2         1712         -              - 
  3         1972         -              - 
  4         2230        6588            - 
  5         2250         -              - 
  6         2108         -              -

我什至尝试输入 WHERE Time.quarter = ((Time.month * 4) / 12) 但是来自外部查询的 month 值没有在子查询中传递。

不幸的是,我对 CASE WHEN 表达式没有足够的经验,不知道如何传递月份行。任何提示都会很棒。

这个怎么样?

示例数据:

SQL> with
  2  time (time_id, month, quarter, year) as
  3    (select 1,  1, 1, 2016 from dual union all
  4     select 2,  2, 1, 2016 from dual union all
  5     select 3,  3, 1, 2016 from dual union all
  6     select 4,  5, 2, 2016 from dual union all
  7     select 5,  7, 3, 2016 from dual union all
  8     select 6,  8, 3, 2016 from dual union all
  9     select 7,  9, 3, 2016 from dual union all
 10     select 8, 10, 4, 2016 from dual union all
 11     select 9, 11, 4, 2016 from dual
 12    ),
 13  sales (time_id, sales) as
 14    (select 1, 100 from dual union all
 15     select 1, 100 from dual union all
 16     select 2, 200 from dual union all
 17     select 3, 300 from dual union all
 18     select 4, 400 from dual union all
 19     select 5, 500 from dual union all
 20     select 6, 600 from dual union all
 21     select 7, 700 from dual union all
 22     select 8, 800 from dual union all
 23     select 9, 900 from dual
 24    ),

查询从这里开始;它以分析形式使用 sum 聚合; partition by 子句表示要计算的内容 row_number,类似地,对每个 quarter/year 中的行进行排序 - 它稍后在 CASE 表达式中用于决定是否显示 quarterly/yearly 总数。

 25  temp as
 26    (select t.month, t.quarter, t.year, sum(s.sales) month_sales
 27      from time t join sales s on s.time_id = t.time_id
 28      where t.year = 2016
 29      group by t.month, t.quarter, t.year
 30    ),
 31  temp2 as
 32    (select month, quarter, month_sales,
 33       sum(month_sales) over (partition by quarter) quarter_sales,
 34       sum(month_sales) over (partition by year   ) year_sales,
 35       row_number() over (partition by quarter order by quarter) rnq,
 36       row_number() over (partition by year    order by null)    rny
 37     from temp
 38    )
 39  select month,
 40    month_sales
 41    case when rnq = 1 then quarter_sales end month_sales,
 42    case when rny = 1 then year_sales end year_sales
 43  from temp2
 44  order by month;

     MONTH MONTH_SALES QUARTER_SALES YEAR_SALES
----------  ---------- ----------- ----------
         1        200         700       4600
         2        200
         3        300
         4        400        1500
         5        500        
         6        600
         7        700        2400
         8        800        
         9        900

9 rows selected.

SQL>