【发布时间】:2022-11-23 21:09:59
【问题描述】:
我有以下场景(CTE SQL 示例),我们有这种粒度的产品销售数据;
- 日期级别
- 来源(设备、国家)
- 会计周期(年、周)
- 产品信息(组)
我有一个使用 Over Partition By,“FYTD”= Fiscal Year To Date 的运行总计,这似乎按预期工作,按不同维度计算运行总计,但是当我在最终结果中求和时,它被夸大了,就像我们一样汇总每天的 FYTD 值,而不是在最近的粒度级别。
我们如何才能在结果中返回截至最近一天的准确、真实的 FYTD 总和,并使用可扩展到具有更多财政年度/周的更大结果集的解决方案?我正在 Snowflake 中对此进行测试。
with rawdata as (
select * from
values
('2022-10-01', 2023, 1, 'Desktop', 'UK', 'Shoes', 1),
('2022-10-01', 2023, 1, 'Mobile', 'UK', 'Shoes', 2),
('2022-10-01', 2023, 1, 'Tablet', 'UK', 'Shoes', 1),
('2022-10-02', 2023, 1, 'Desktop', 'UK', 'Shoes', 1),
('2022-10-02', 2023, 1, 'Mobile', 'UK', 'Shoes', 2),
('2022-10-02', 2023, 1, 'Tablet', 'UK', 'Shoes', 4),
('2022-10-03', 2023, 1, 'Desktop', 'UK', 'Shoes', 1),
('2022-10-03', 2023, 1, 'Mobile', 'UK', 'Shoes', 2),
('2022-10-03', 2023, 1, 'Tablet', 'UK', 'Shoes', 5),
('2022-10-01', 2023, 1, 'Desktop', 'UK', 'Socks', 1),
('2022-10-01', 2023, 1, 'Mobile', 'UK', 'Socks', 2),
('2022-10-01', 2023, 1, 'Tablet', 'UK', 'Socks', 1),
('2022-10-02', 2023, 1, 'Desktop', 'UK', 'Socks', 1),
('2022-10-02', 2023, 1, 'Mobile', 'UK', 'Socks', 2),
('2022-10-02', 2023, 1, 'Tablet', 'UK', 'Socks', 4),
('2022-10-03', 2023, 1, 'Desktop', 'UK', 'Socks', 1),
('2022-10-03', 2023, 1, 'Mobile', 'UK', 'Socks', 2),
('2022-10-03', 2023, 1, 'Tablet', 'UK', 'Socks', 5)
as a (date, fiscalyearno, fiscalweekno, devicegroup, usercountry, productgroup, bookings)
),
resultsset as (
select date
, fiscalyearno
, fiscalweekno
, devicegroup
, usercountry
, productgroup
, sum(bookings) as totalbookings
, sum(totalbookings)
over
(partition by fiscalyearno, fiscalweekno, devicegroup, usercountry, productgroup order by date asc) as fytdbookings
from rawdata
group by 1,2,3,4,5,6
)
select fiscalyearno, fiscalweekno, sum(totalbookings), sum(fytdbookings)
from resultsset
group by 1,2
已尝试对最大 FYTD 值求和,但收到语法警告,指出您不能拥有嵌套聚合。
dense_rank() 有帮助但不确定是否是最佳解决方案;
with rawdata as (
select * from
values
('2022-10-01', 2023, 1, 'Desktop', 'UK', 'Shoes', 1),
('2022-10-01', 2023, 1, 'Mobile', 'UK', 'Shoes', 2),
('2022-10-01', 2023, 1, 'Tablet', 'UK', 'Shoes', 1),
('2022-10-02', 2023, 1, 'Desktop', 'UK', 'Shoes', 1),
('2022-10-02', 2023, 1, 'Mobile', 'UK', 'Shoes', 2),
('2022-10-02', 2023, 1, 'Tablet', 'UK', 'Shoes', 4),
('2022-10-03', 2023, 1, 'Desktop', 'UK', 'Shoes', 1),
('2022-10-03', 2023, 1, 'Mobile', 'UK', 'Shoes', 2),
('2022-10-03', 2023, 1, 'Tablet', 'UK', 'Shoes', 5),
('2022-10-01', 2023, 1, 'Desktop', 'UK', 'Socks', 1),
('2022-10-01', 2023, 1, 'Mobile', 'UK', 'Socks', 2),
('2022-10-01', 2023, 1, 'Tablet', 'UK', 'Socks', 1),
('2022-10-02', 2023, 1, 'Desktop', 'UK', 'Socks', 1),
('2022-10-02', 2023, 1, 'Mobile', 'UK', 'Socks', 2),
('2022-10-02', 2023, 1, 'Tablet', 'UK', 'Socks', 4),
('2022-10-03', 2023, 1, 'Desktop', 'UK', 'Socks', 1),
('2022-10-03', 2023, 1, 'Mobile', 'UK', 'Socks', 2),
('2022-10-03', 2023, 1, 'Tablet', 'UK', 'Socks', 5),
('2022-10-08', 2023, 2, 'Desktop', 'UK', 'Shoes', 7),
('2022-10-08', 2023, 2, 'Mobile', 'UK', 'Shoes', 8),
('2022-10-08', 2023, 2, 'Tablet', 'UK', 'Shoes', 4),
('2022-10-09', 2023, 2, 'Desktop', 'UK', 'Shoes', 6),
('2022-10-09', 2023, 2, 'Mobile', 'UK', 'Shoes', 2),
('2022-10-09', 2023, 2, 'Tablet', 'UK', 'Shoes', 8),
('2022-10-10', 2023, 2, 'Desktop', 'UK', 'Shoes', 12),
('2022-10-10', 2023, 2, 'Mobile', 'UK', 'Shoes', 22),
('2022-10-10', 2023, 2, 'Tablet', 'UK', 'Shoes', 5),
('2022-10-08', 2023, 2, 'Desktop', 'UK', 'Socks', 4),
('2022-10-08', 2023, 2, 'Mobile', 'UK', 'Socks', 1),
('2022-10-08', 2023, 2, 'Tablet', 'UK', 'Socks', 2),
('2022-10-09', 2023, 2, 'Desktop', 'UK', 'Socks', 3),
('2022-10-09', 2023, 2, 'Mobile', 'UK', 'Socks', 8),
('2022-10-09', 2023, 2, 'Tablet', 'UK', 'Socks', 9),
('2022-10-10', 2023, 2, 'Desktop', 'UK', 'Socks', 5),
('2022-10-10', 2023, 2, 'Mobile', 'UK', 'Socks', 4),
('2022-10-10', 2023, 2, 'Tablet', 'UK', 'Socks', 13)
as a (date, fiscalyearno, fiscalweekno, devicegroup, usercountry, productgroup, bookings)
),
resultsset as (
select date
, fiscalyearno
, fiscalweekno
, devicegroup
, usercountry
, productgroup
, sum(bookings) as totalbookings
, dense_rank()
over
(partition by fiscalyearno, devicegroup, usercountry, productgroup order by date desc, fiscalweekno desc) as fytddr
, sum(totalbookings)
over
(partition by fiscalyearno, devicegroup, usercountry, productgroup order by date, fiscalweekno asc) as fytdbookings
from rawdata
group by 1,2,3,4,5,6
)
//select * from resultsset
//order by 1,2,3,4,5,6
select fiscalyearno
, fiscalweekno
, sum(totalbookings) as totalbookings
, sum(iff(fytddr = 1, fytdbookings, 0)) as fytdbookings
from resultsset
group by 1,2
order by 2
【问题讨论】:
-
我可以将 partition by fiscysearno order by fiscalweekno 的总和移动到最终查询中,以获得该特定用例的正确结果,但随着需求的变化,我们可能需要也可能不需要某个维度的 FYTD total,我们需要确保它是在结果集和最终结果中。
标签: sql snowflake-cloud-data-platform