[英]Calculate Cumulative Sum-Running Total/Sale for Each Day of the Month in Redshift
问题陈述:获得每个产品每个日历日期的持续销售。
简要背景:进行销售时,会将条目添加到销售表中。 如果特定产品在特定日期没有进行任何销售,则不会插入任何记录。
销售表结构。
+------------+--------------+------------+
| date | Product Code | total_sale |
+------------+--------------+------------+
| 2020-01-15 | abc | 100 |
| 2020-01-16 | abc | 200 |
| 2020-01-17 | abc | 200 |
| 2020-01-16 | tvc | 200 |
| 2020-01-16 | sfr | 200 |
+------------+--------------+------------+
SQL 生成上述视图。
create temporary table sales_daily as
select '20200115' :: date as sales_day, 'abc' as product_Code , 100 as sales
Union all
select '20200116' :: date as sales_day, 'abc' as product_Code , 200 as sales
Union all
select '20200117' :: date as sales_day, 'abc' as product_Code , 200 as sales
Union all
select '20200115' :: date as sales_day, 'tvc' as product_Code , 200 as sales
Union all
select '20200115' :: date as sales_day, 'sfr' as product_Code , 200 as sales
;
select * from sales_Daily;
预期 Output:对于一个月中的每个日历日(在这种情况下为 2020 年 1 月)获得最近 n 天的滚动销售(此数字可以是任何数字,并将在最终查询中进行编码)。
采取的步骤:为此,我已经尝试了现有的日历表(用于创建下面共享的日历表的片段)并求和 window function。但是,由于需要使用按产品代码划分的每个产品代码计算滚动总和,而不是在产品级别求和日级别。 我知道这是预期的行为。 我的问题是使用 redshift 来解决这个问题陈述时应该采用什么方法。 此外,是否可以使用 window function 解决问题陈述。
SQL 创建日历表:
create temporary table calendar as
select '20200101' :: date As calendar_day Union all
select '20200102' :: date As calendar_day Union all
select '20200103' :: date As calendar_day Union all
select '20200104' :: date As calendar_day Union all
select '20200105' :: date As calendar_day Union all
select '20200106' :: date As calendar_day Union all
select '20200107' :: date As calendar_day Union all
select '20200108' :: date As calendar_day Union all
select '20200109' :: date As calendar_day Union all
select '20200110' :: date As calendar_day Union all
select '20200111' :: date As calendar_day Union all
select '20200112' :: date As calendar_day Union all
select '20200113' :: date As calendar_day Union all
select '20200114' :: date As calendar_day Union all
select '20200115' :: date As calendar_day Union all
select '20200116' :: date As calendar_day Union all
select '20200117' :: date As calendar_day Union all
select '20200118' :: date As calendar_day Union all
select '20200119' :: date As calendar_day Union all
select '20200120' :: date As calendar_day Union all
select '20200121' :: date As calendar_day Union all
select '20200122' :: date As calendar_day Union all
select '20200123' :: date As calendar_day Union all
select '20200124' :: date As calendar_day Union all
select '20200125' :: date As calendar_day Union all
select '20200126' :: date As calendar_day Union all
select '20200127' :: date As calendar_day Union all
select '20200128' :: date As calendar_day Union all
select '20200129' :: date As calendar_day Union all
select '20200130' :: date As calendar_day Union all
select '20200131' :: date As calendar_day
;
SQL 现在用于最终 Output:
select
calendar_Day,
sales_day,
product_Code,
sales,
sum(sales) over (partition by product_Code order by calendar_Day rows between 1 PRECEDING and current row) running_salest1day
from calendar
left join sales_daily on calendar_day :: date = sales_day :: date
您将不得不使用 window function 来计算累积总和。 下面的查询为每个产品和每个日历日创建虚拟 0 值销售额。 这将确保 output 具有每个产品和每个日历日的累积销售值行。
select sales_day as Calendar_Day,
product_Code,
sales,
sum(sales) over (partition by product_Code order by sales_day rows between 1 PRECEDING and current row) running_salest1day
from (
select sales_day, product_Code, sum(sales) as sales
from (
select sales_day, product_Code, sales -- Actual Sales entry
from sales_daily
union all
select calendar_day as sales_day, dp.product_Code, 0 as sales -- Dummy Sales entry for each date
from (
select distinct product_Code from sales_daily
) dp cross join calendar
) sd
group by sales_day, product_Code
) asd
这是SQL 小提琴。
使用日期和产品之间的cross join
生成行。 然后使用累积和。 所以:
select c.calendar_Day, p.product_Code, sales,
sum(sales) over (partition by p.product_code
order by c.calendar_Day
rows between n preceding and current row
) and running_sales
from calendar c cross join
(select distinct product_code from sales_daily) p left join
sales_daily s
on c.calendar_day = s.sales_day and p.product_code = s.product_code
order by p.product_code, c.calendar_day;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.