set search_path=tds; create table month_end_balance_fact ( year_month int, product_sk int, month_end_amount_balance numeric(10,2), month_end_quantity_balance int ); comment on table month_end_balance_fact is '累积度量事实表'; comment on column month_end_balance_fact.year_month is '年月'; comment on column month_end_balance_fact.product_sk is '产品代理键'; comment on column month_end_balance_fact.month_end_amount_balance is '累积金额'; comment on column month_end_balance_fact.month_end_quantity_balance is '累积数量';
insert into month_end_balance_fact select a.year_month, b.product_sk, sum(b.month_order_amount) month_order_amount, sum(b.month_order_quantity) month_order_quantity from (select distinct year_month, year_month/100 year1, year_month - year_month/100*100 month1 from v_month_end_sales_order_fact) a, (select *, year_month/100 year1, year_month - year_month/100*100 month1, max(year_month) over () max_year_month from v_month_end_sales_order_fact) b where a.year_month <= b.max_year_month and a.year1 = b.year1 and b.month1 <= a.month1 group by a.year_month, b.product_sk;子查询获取month_end_sales_order_fact表的数据,及其年月和最大月份代理键。外层查询汇总每年一月到当月的累积销售数据,a.year_month <= b.max_year_month条件用于限定只统计到现存的最大月份为止。
select year_month, product_sk psk, month_order_amount amt, month_order_quantity qty from v_month_end_sales_order_fact order by year_month, psk;查询结构如图1所示。
select year_month, product_sk psk, month_end_amount_balance amt, month_end_quantity_balance qty from month_end_balance_fact order by year_month, psk;查询结构如图2所示。
insert into month_end_balance_fact select year_month, product_sk, sum(month_order_amount), sum(month_order_quantity) from (select * from v_month_end_sales_order_fact where year_month = :v_year_month union all select :v_year_month, product_sk product_sk, month_end_amount_balance month_order_amount, month_end_quantity_balance month_order_quantity from month_end_balance_fact where year_month in (select max(case when :v_year_month - :v_year_month/100*100 = 1 then 0 else year_month end) from month_end_balance_fact)) t group by year_month, product_sk;子查询将累积度量表和月周期快照表做并集操作,增加上月的累积数据。最外层查询执行销售数据按月和产品的分组聚合。最内层的case语句用于在每年一月时重新归零再累积。:v_year_month以是年月参数。
select fn_month_sum(201706);执行累积度量定期装载脚本,以shell命令`date +%Y%m`的输出作为年月参数传入month_balance_sum.sql文件中。
su - gpadmin -c 'export PGPASSWORD=123456;psql -U dwtest -d dw -h hdp3 -v v_year_month=''`date +%Y%m`'' -f ~/month_balance_sum.sql'执行和前面初始装载后相同的查询,周期快照表和累积度量表的查询结果分别如图3、图4所示。
dw=> select year_month, sum(month_end_amount_balance) s dw-> from month_end_balance_fact dw-> group by year_month dw-> order by year_month; year_month | s ------------+----------- 201603 | 191158.00 201604 | 345600.00 201605 | 455772.00 201606 | 572190.00 201705 | 253400.00 201706 | 272086.00 (6 rows)
而通过月份累加月底金额:
dw=> select product_name, sum(month_end_amount_balance) s dw-> from month_end_balance_fact a, dw-> product_dim b dw-> where a.product_sk = b.product_sk dw-> group by product_name dw-> order by product_name; product_name | s -----------------+----------- flat panel | 99332.00 floppy drive | 927195.00 hard disk drive | 932285.00 keyboard | 125220.00 lcd panel | 6174.00 (5 rows)
以上查询结果是错误的。正确的结果应该和下面的在month_end_sales_order_fact表上进行的查询结果相同。
dw=> select product_name, sum(month_order_amount) s dw-> from month_end_sales_order_fact a, dw-> product_dim b dw-> where a.product_sk = b.product_sk dw-> group by product_name dw-> order by product_name; product_name | s -----------------+----------- flat panel | 49666.00 floppy drive | 348655.00 hard disk drive | 375481.00 keyboard | 67387.00 lcd panel | 3087.00 (5 rows)
create view v_month_end_balance_fact as select a.year_month, b.product_sk, sum(b.month_order_amount) month_order_amount, sum(b.month_order_quantity) month_order_quantity from (select distinct year_month, year_month/100 year1, year_month - year_month/100*100 month1 from v_month_end_sales_order_fact) a, (select *, year_month/100 year1, year_month - year_month/100*100 month1, max(year_month) over () max_year_month from month_end_sales_order_fact) b where a.year_month <= b.max_year_month and a.year1 = b.year1 and b.month1 <= a.month1 group by a.year_month, b.product_sk;