[英]Get a cumulative sum for each month in oracle sql
Hi I have a table with 3 columns.嗨,我有一个 3 列的表。
custid p_date vegetable
0000009 07-APR-20 tomato
0000013 25-MAR-20 potato
0000015 11-APR-19 tomato
0000016 23-JUL-18 potato
0000019 19-JUL-18 potato
0000018 07-JUN-20 turnip
0000020 12-JUL-18 turnip
0000022 23-JUL-18 potato
0000023 12-JUL-18 turnip
0000024 11-AUG-20 potato
I need to calculate the distinct count for the customers based on the veggie column along with cumulative sum for each month我需要根据 veggie 列以及每个月的累积总和计算客户的不同计数
the output should have below columns output 应具有以下列
date
tomato_ct
cum_tomato_ct
potato_ct
cum_potato_ct
turnip_ct
cum_turnip_ct
If you want monthly counts and cumulative counts pivoted by vegetable, you can do:如果您想要以蔬菜为中心的每月计数和累积计数,您可以执行以下操作:
select trunc(p_date, 'month') as p_month,
sum(case when vegetable = 'tomato' then 1 else 0 end) as tomato_ct,
sum(sum(case when vegetable = 'tomato' then 1 else 0 end)) over(order by trunc(p_date, 'month')) as cum_tomato_ct,
sum(case when vegetable = 'potato' then 1 else 0 end) as potato_ct,
sum(sum(case when vegetable = 'potato' then 1 else 0 end)) over(order by trunc(p_date, 'month')) as cum_potato_ct,
sum(case when vegetable = 'turnip' then 1 else 0 end) as turnip_ct,
sum(sum(case when vegetable = 'turnip' then 1 else 0 end)) over(order by trunc(p_date, 'month')) as cum_turnip_ct
from mytable
group by trunc(p_date, 'month')
You mentioned that you want a count of distinct customers.您提到您想要统计不同的客户。 If you want to count each customer only once par vegetable, on their earliest appearance, then I would recommend two levels of aggregation:
如果您只想在他们最早出现的情况下对每个客户计算一次普通蔬菜,那么我建议使用两个级别的聚合:
select trunc(p_date, 'month') as p_month,
sum(case when vegetable = 'tomato' then 1 else 0 end) as tomato_ct,
sum(sum(case when vegetable = 'tomato' then 1 else 0 end)) over(order by trunc(p_date, 'month')) as cum_tomato_ct,
sum(case when vegetable = 'potato' then 1 else 0 end) as potato_ct,
sum(sum(case when vegetable = 'potato' then 1 else 0 end)) over(order by trunc(p_date, 'month')) as cum_potato_ct,
sum(case when vegetable = 'turnip' then 1 else 0 end) as turnip_ct,
sum(sum(case when vegetable = 'turnip' then 1 else 0 end)) over(order by trunc(p_date, 'month')) as cum_turnip_ct
from (
select cust_id, vegetable, min(p_date) as p_date
from mytable
group by cust_id, vegetable
) t
group by trunc(p_date, 'month')
You can use the combination of analytical
function and GROUP BY
as follows:您可以使用
analytical
function 和GROUP BY
的组合,如下所示:
SQL>
SQL> -- sample data
SQL> WITH YOUR_TABLE(custid, p_date, vegetable) AS
2 (SELECT '0000009', TO_DATE('07-APR-20','DD-MON-RR'), 'tomato' FROM DUAL UNION ALL
3 SELECT '0000013', TO_DATE('25-MAR-20','DD-MON-RR'), 'potato' FROM DUAL UNION ALL
4 SELECT '0000015', TO_DATE('11-APR-19','DD-MON-RR'), 'tomato' FROM DUAL UNION ALL
5 SELECT '0000016', TO_DATE('23-JUL-18','DD-MON-RR'), 'potato' FROM DUAL UNION ALL
6 SELECT '0000019', TO_DATE('19-JUL-18','DD-MON-RR'), 'potato' FROM DUAL UNION ALL
7 SELECT '0000018', TO_DATE('07-JUN-20','DD-MON-RR'), 'turnip' FROM DUAL UNION ALL
8 SELECT '0000020', TO_DATE('12-JUL-18','DD-MON-RR'), 'turnip' FROM DUAL UNION ALL
9 SELECT '0000022', TO_DATE('23-JUL-18','DD-MON-RR'), 'potato' FROM DUAL UNION ALL
10 SELECT '0000023', TO_DATE('12-JUL-18','DD-MON-RR'), 'turnip' FROM DUAL UNION ALL
11 SELECT '0000024', TO_DATE('11-AUG-20','DD-MON-RR'), 'potato' FROM DUAL)
12 -- actual query starts from here
13 SELECT P_DATE,
14 COUNT(CASE WHEN vegetable = 'tomato' THEN 1 END) AS TOMATO_CT,
15 MAX(TOMATO_CNT) AS CUM_TOMATO_CT,
16 COUNT(CASE WHEN vegetable = 'potato' THEN 1 END) AS POTATO_CT,
17 MAX(POTATO_CNT) AS CUM_POTATO_CT,
18 COUNT(CASE WHEN vegetable = 'turnip' THEN 1 END) AS TURNIP_CT,
19 MAX(TURNIP_CNT) AS CUM_TURNIP_CT
20 FROM
21 (SELECT T.*,
22 COUNT(CASE WHEN vegetable = 'tomato' THEN 1 END) OVER (ORDER BY P_DATE) AS TOMATO_CNT,
23 COUNT(CASE WHEN vegetable = 'potato' THEN 1 END) OVER (ORDER BY P_DATE) AS POTATO_CNT,
24 COUNT(CASE WHEN vegetable = 'turnip' THEN 1 END) OVER (ORDER BY P_DATE) AS TURNIP_CNT
25 FROM (SELECT DISTINCT custid, TRUNC(p_date,'MON') P_DATE, vegetable FROM YOUR_TABLE) T
26 )
27 GROUP BY P_DATE
28 ORDER BY P_DATE;
P_DATE TOMATO_CT CUM_TOMATO_CT POTATO_CT CUM_POTATO_CT TURNIP_CT CUM_TURNIP_CT
-------------------- ---------- ------------- ---------- ------------- ---------- -------------
01-JUL-2018 00:00:00 0 0 3 3 2 2
01-APR-2019 00:00:00 1 1 0 3 0 2
01-MAR-2020 00:00:00 0 1 1 4 0 2
01-APR-2020 00:00:00 1 2 0 4 0 2
01-JUN-2020 00:00:00 0 2 0 4 1 3
01-AUG-2020 00:00:00 0 2 1 5 0 3
6 rows selected.
SQL>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.