前 7 天销售
First 7 days sales
我想查看某件商品自销售第一天起 7 天内的金额总和。基本上,我想查看前 7 天的销售额总和。
我正在使用以下查询。
select item, sum(amt)
from table
where first_sale_dt = (first_sale_dt + 6).
当我运行这个查询时,我没有得到任何结果。
你的代码目前不会给你任何结果,因为你正在查看每一行,并且询问值 first_sale_dt
是否等于它不是 +6
[=21= 的值]
您需要使用 WINDOW 函数来查看许多行,或者自行加入 table 并过滤连接的行以提供您想要的结果。
所以用数据的CTE进行测试:
WITH data as (
select * from values
(1, 2, '2022-03-01'::date),
(1, 4, '2022-03-04'::date),
(1, 200,'2022-04-01'::date),
(3, 20, '2022-03-01'::date)
t(item, amt, first_sale_dt)
)
这个 SQL 显示我们想要求和的筛选行,它使用 sub-select(可以移到 CTE 中)找到要执行的“首次销售”的日期范围。
select a.item, b.amt
from (
select
item,
min(first_sale_dt) as first_first_sale_dt
from data
group by 1
) as a
join data as b
on a.item = b.item and b.first_sale_dt <= (a.first_first_sale_dt + 6)
ITEM
AMT
1
2
1
4
3
20
因此添加了 SUM:
select a.item, sum(b.amt)
from (
select
item,
min(first_sale_dt) as first_first_sale_dt
from data
group by 1
) as a
join data as b
on a.item = b.item and b.first_sale_dt <= (a.first_first_sale_dt + 6)
group by 1;
你得到:
ITEM
SUM(B.AMT)
1
6
3
20
滑动Window:
这依赖于密集数据(每天 1 行),而且滑动 WINDOW 正在做的工作正在被丢弃,这是一个字符串标志,这不是高性能的解决方案,我会坚持第一个解决方案。
WITH data as (
select * from values
(1, 2, '2022-03-01'::date),
(1, 2, '2022-03-02'::date),
(1, 2, '2022-03-03'::date),
(1, 2, '2022-03-04'::date),
(1, 2, '2022-03-05'::date),
(1, 2, '2022-03-06'::date),
(1, 2, '2022-03-07'::date),
(1, 2, '2022-03-08'::date)
t(item, amt, first_sale_dt)
)
select item,
first_sale_dt,
sum(amt) over(partition by item order by first_sale_dt rows BETWEEN current row and 6 following ) as s
,count(amt) over(partition by item order by first_sale_dt rows BETWEEN current row and 6 following ) as c
from data
order by 2;
ITEM
FIRST_SALE_DT
S
C
1
2022-03-01
14
7
1
2022-03-02
14
7
1
2022-03-03
12
6
1
2022-03-04
10
5
1
2022-03-05
8
4
1
2022-03-06
6
3
1
2022-03-07
4
2
1
2022-03-08
2
1
因此您需要过滤掉一些行。
WITH data as (
select * from values
(1, 2, '2022-03-01'::date),
(1, 2, '2022-03-02'::date),
(1, 2, '2022-03-03'::date),
(1, 2, '2022-03-04'::date),
(1, 2, '2022-03-05'::date),
(1, 2, '2022-03-06'::date),
(1, 2, '2022-03-07'::date),
(1, 2, '2022-03-08'::date)
t(item, amt, first_sale_dt)
)
select item,
sum(amt) over(partition by item order by first_sale_dt rows BETWEEN current row and 6 following ) as s
from data
qualify row_number() over (partition by item order by first_sale_dt) = 1
给出:
ITEM
S
1
14
如果你真的要用window function
。这是初学者友好的版本
with cte as
(select *, min(sale_date) over (partition by item) as sale_start_date
from data) --thanks Simeon
select item, sum(amt) as amount
from cte
where sale_date <= sale_start_date + 6 --limit to first week
group by item;
附带说明一下,我建议在日期
上使用 dateadd
而不是 +
我想查看某件商品自销售第一天起 7 天内的金额总和。基本上,我想查看前 7 天的销售额总和。
我正在使用以下查询。
select item, sum(amt)
from table
where first_sale_dt = (first_sale_dt + 6).
当我运行这个查询时,我没有得到任何结果。
你的代码目前不会给你任何结果,因为你正在查看每一行,并且询问值 first_sale_dt
是否等于它不是 +6
[=21= 的值]
您需要使用 WINDOW 函数来查看许多行,或者自行加入 table 并过滤连接的行以提供您想要的结果。
所以用数据的CTE进行测试:
WITH data as (
select * from values
(1, 2, '2022-03-01'::date),
(1, 4, '2022-03-04'::date),
(1, 200,'2022-04-01'::date),
(3, 20, '2022-03-01'::date)
t(item, amt, first_sale_dt)
)
这个 SQL 显示我们想要求和的筛选行,它使用 sub-select(可以移到 CTE 中)找到要执行的“首次销售”的日期范围。
select a.item, b.amt
from (
select
item,
min(first_sale_dt) as first_first_sale_dt
from data
group by 1
) as a
join data as b
on a.item = b.item and b.first_sale_dt <= (a.first_first_sale_dt + 6)
ITEM | AMT |
---|---|
1 | 2 |
1 | 4 |
3 | 20 |
因此添加了 SUM:
select a.item, sum(b.amt)
from (
select
item,
min(first_sale_dt) as first_first_sale_dt
from data
group by 1
) as a
join data as b
on a.item = b.item and b.first_sale_dt <= (a.first_first_sale_dt + 6)
group by 1;
你得到:
ITEM | SUM(B.AMT) |
---|---|
1 | 6 |
3 | 20 |
滑动Window:
这依赖于密集数据(每天 1 行),而且滑动 WINDOW 正在做的工作正在被丢弃,这是一个字符串标志,这不是高性能的解决方案,我会坚持第一个解决方案。
WITH data as (
select * from values
(1, 2, '2022-03-01'::date),
(1, 2, '2022-03-02'::date),
(1, 2, '2022-03-03'::date),
(1, 2, '2022-03-04'::date),
(1, 2, '2022-03-05'::date),
(1, 2, '2022-03-06'::date),
(1, 2, '2022-03-07'::date),
(1, 2, '2022-03-08'::date)
t(item, amt, first_sale_dt)
)
select item,
first_sale_dt,
sum(amt) over(partition by item order by first_sale_dt rows BETWEEN current row and 6 following ) as s
,count(amt) over(partition by item order by first_sale_dt rows BETWEEN current row and 6 following ) as c
from data
order by 2;
ITEM | FIRST_SALE_DT | S | C |
---|---|---|---|
1 | 2022-03-01 | 14 | 7 |
1 | 2022-03-02 | 14 | 7 |
1 | 2022-03-03 | 12 | 6 |
1 | 2022-03-04 | 10 | 5 |
1 | 2022-03-05 | 8 | 4 |
1 | 2022-03-06 | 6 | 3 |
1 | 2022-03-07 | 4 | 2 |
1 | 2022-03-08 | 2 | 1 |
因此您需要过滤掉一些行。
WITH data as (
select * from values
(1, 2, '2022-03-01'::date),
(1, 2, '2022-03-02'::date),
(1, 2, '2022-03-03'::date),
(1, 2, '2022-03-04'::date),
(1, 2, '2022-03-05'::date),
(1, 2, '2022-03-06'::date),
(1, 2, '2022-03-07'::date),
(1, 2, '2022-03-08'::date)
t(item, amt, first_sale_dt)
)
select item,
sum(amt) over(partition by item order by first_sale_dt rows BETWEEN current row and 6 following ) as s
from data
qualify row_number() over (partition by item order by first_sale_dt) = 1
给出:
ITEM | S |
---|---|
1 | 14 |
如果你真的要用window function
。这是初学者友好的版本
with cte as
(select *, min(sale_date) over (partition by item) as sale_start_date
from data) --thanks Simeon
select item, sum(amt) as amount
from cte
where sale_date <= sale_start_date + 6 --limit to first week
group by item;
附带说明一下,我建议在日期
上使用dateadd
而不是 +