繁体   English   中英

在 Redshift 中计算每月每一天的累积总和运行总额/销售额

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM