如何按时间范围内的组进行分区?
How can I partition by group that falls within a time range?
我有以下 table 显示客户何时购买某种产品。我的数据是CustomerID, Amount, Dat
。我正在尝试创建列 ProductsIn30Days
,它表示客户在 Dat-30
天(包括当天)范围内购买了多少产品。
例如,ProductsIn30Days
for CustomerID
1 on Dat
25.3.2020 是 7,因为客户在 25.3.2020 购买了 2 件产品,在 24.3.2020 又购买了 5 件产品, 落在 25.3.2020 之前的 30 天内。
CustomerID
Amount
Dat
ProductsIn30Days
1
1
23.3.2018
1
1
2
24.3.2020
2
1
3
24.3.2020
5
1
2
25.3.2020
7
1
2
24.5.2020
2
1
1
15.6.2020
3
2
7
24.3.2017
7
2
2
24.3.2020
2
我试过类似的方法但没有成功,因为分区只适用于单个日期,而不是我需要的范围:
select CustomerID, Amount, Dat,
sum(Amount) over (partition by CustomerID, Dat-30)
from table
感谢您的帮助。
您可以使用范围为 window:
的解析 SUM
函数
SELECT t.*,
SUM(Amount) OVER (
PARTITION BY CustomerID
ORDER BY Dat
RANGE BETWEEN INTERVAL '30' DAY PRECEDING AND CURRENT ROW
) AS ProductsIn30Days
FROM table_name t;
其中,对于示例数据:
CREATE TABLE table_name (CustomerID, Amount, Dat) AS
SELECT 1, 1, DATE '2018-03-23' FROM DUAL UNION ALL
SELECT 1, 2, DATE '2020-03-24' FROM DUAL UNION ALL
SELECT 1, 3, DATE '2020-03-24' FROM DUAL UNION ALL
SELECT 1, 2, DATE '2020-03-25' FROM DUAL UNION ALL
SELECT 1, 2, DATE '2020-05-24' FROM DUAL UNION ALL
SELECT 1, 1, DATE '2020-06-15' FROM DUAL UNION ALL
SELECT 2, 7, DATE '2017-03-24' FROM DUAL UNION ALL
SELECT 2, 2, DATE '2020-03-24' FROM DUAL;
输出:
CUSTOMERID
AMOUNT
DAT
PRODUCTSIN30DAYS
1
1
2018-03-23 00:00:00
1
1
2
2020-03-24 00:00:00
5
1
3
2020-03-24 00:00:00
5
1
2
2020-03-25 00:00:00
7
1
2
2020-05-24 00:00:00
2
1
1
2020-06-15 00:00:00
3
2
7
2017-03-24 00:00:00
7
2
2
2020-03-24 00:00:00
2
注意:如果您有同一日期的值,那么它们将按顺序绑定并始终聚合在一起(即第 2 行和第 3 行)。如果您希望将它们单独聚合,那么您需要通过其他方式进行排序以打破联系,但这不适用于 RANGE
window.
db<>fiddle here
我有以下 table 显示客户何时购买某种产品。我的数据是CustomerID, Amount, Dat
。我正在尝试创建列 ProductsIn30Days
,它表示客户在 Dat-30
天(包括当天)范围内购买了多少产品。
例如,ProductsIn30Days
for CustomerID
1 on Dat
25.3.2020 是 7,因为客户在 25.3.2020 购买了 2 件产品,在 24.3.2020 又购买了 5 件产品, 落在 25.3.2020 之前的 30 天内。
CustomerID | Amount | Dat | ProductsIn30Days |
---|---|---|---|
1 | 1 | 23.3.2018 | 1 |
1 | 2 | 24.3.2020 | 2 |
1 | 3 | 24.3.2020 | 5 |
1 | 2 | 25.3.2020 | 7 |
1 | 2 | 24.5.2020 | 2 |
1 | 1 | 15.6.2020 | 3 |
2 | 7 | 24.3.2017 | 7 |
2 | 2 | 24.3.2020 | 2 |
我试过类似的方法但没有成功,因为分区只适用于单个日期,而不是我需要的范围:
select CustomerID, Amount, Dat,
sum(Amount) over (partition by CustomerID, Dat-30)
from table
感谢您的帮助。
您可以使用范围为 window:
的解析SUM
函数
SELECT t.*,
SUM(Amount) OVER (
PARTITION BY CustomerID
ORDER BY Dat
RANGE BETWEEN INTERVAL '30' DAY PRECEDING AND CURRENT ROW
) AS ProductsIn30Days
FROM table_name t;
其中,对于示例数据:
CREATE TABLE table_name (CustomerID, Amount, Dat) AS
SELECT 1, 1, DATE '2018-03-23' FROM DUAL UNION ALL
SELECT 1, 2, DATE '2020-03-24' FROM DUAL UNION ALL
SELECT 1, 3, DATE '2020-03-24' FROM DUAL UNION ALL
SELECT 1, 2, DATE '2020-03-25' FROM DUAL UNION ALL
SELECT 1, 2, DATE '2020-05-24' FROM DUAL UNION ALL
SELECT 1, 1, DATE '2020-06-15' FROM DUAL UNION ALL
SELECT 2, 7, DATE '2017-03-24' FROM DUAL UNION ALL
SELECT 2, 2, DATE '2020-03-24' FROM DUAL;
输出:
CUSTOMERID AMOUNT DAT PRODUCTSIN30DAYS 1 1 2018-03-23 00:00:00 1 1 2 2020-03-24 00:00:00 5 1 3 2020-03-24 00:00:00 5 1 2 2020-03-25 00:00:00 7 1 2 2020-05-24 00:00:00 2 1 1 2020-06-15 00:00:00 3 2 7 2017-03-24 00:00:00 7 2 2 2020-03-24 00:00:00 2
注意:如果您有同一日期的值,那么它们将按顺序绑定并始终聚合在一起(即第 2 行和第 3 行)。如果您希望将它们单独聚合,那么您需要通过其他方式进行排序以打破联系,但这不适用于 RANGE
window.
db<>fiddle here