我正在尝试编写一个查询,对于过去 44 天的每一天,返回该天之前 7 天窗口中的租赁计数。
这很棘手,因为并非集合中的所有日期都是连续的,并且没有租金的日期不是数据集中的行。
这是我下载数据的位置: https://www.postgresqltutorial.com/postgresql-sample-database/
我知道这需要使用 WINDOW 函数,并且很可能需要使用 ORDER BY 子句,但我的结果返回的是看起来像是运行总和的内容,而不是每个日期之前每 7 天的滚动总和。这是我的代码:
WITH t AS (
SELECT date_trunc('day', rental_date) rental_date, count(rental_id) cnt
FROM rental
WHERE rental_date >= CURRENT_DATE - INTERVAL '44 DAYS'
GROUP BY 1
)
SELECT rental_date, SUM(cnt) OVER w
FROM t
WINDOW w AS (ORDER BY rental_date ROWS BETWEEN 7 PRECEDING AND CURRENT ROW)
ORDER BY rental_date DESC;
预期的输出类似于:
Col1 Col2
date_trunc1 count(rental_id)
2006-02-21 00:00:00 182
2006-02-20 00:00:00 182
2006-02-19 00:00:00 182
2006-02-18 00:00:00 182
2006-02-17 00:00:00 182
2006-02-16 00:00:00 182
2006-02-15 00:00:00 182
2005-08-30 00:00:00 598
2005-08-29 00:00:00 1224
2005-08-28 00:00:00 1883
2005-08-27 00:00:00 2507
2005-08-26 00:00:00 3135
2005-08-25 00:00:00 3756
2005-08-24 00:00:00 4349
2005-08-23 00:00:00 3374
2005-08-22 00:00:00 3148
2005-08-21 00:00:00 2489
2005-08-20 00:00:00 1865
2005-08-19 00:00:00 1237
2005-08-18 00:00:00 616
2005-08-17 00:00:00 23
2005-08-16 00:00:00 0
2005-08-08 00:00:00 671
2005-08-07 00:00:00 1305
*数据集中不存在像“2005-08-08”和“2005-08-07”这样的奇怪的BC日期,因为那些日子没有发生租赁,但它们需要出现在输出,因为租赁确实发生在“2005-08-01”和“2005-07-30”之前的 7 天内。
最佳答案
我想你想要:
SELECT r.*
FROM (SELECT date_trunc('day', rental_date) as rental_date, COUNT(*) as day_count,
SUM(COUNT(*)) OVER (ORDER BY MIN(rental_date) RANGE BETWEEN INTERVAL '7 DAY' PRECEDING AND CURRENT ROW)
FROM rental
GROUP BY date_trunc('day', rental_date)
) r
WHERE rental_date >= CURRENT_DATE - INTERVAL '44 DAY'
ORDER BY rental_date DESC;
即:
- 窗口框架应为
RANGE
,而不是ROWS
。 - 整个时间范围的过滤应该在窗口函数之后进行。
- 7 天总计是指当前行之前的 7 天到当前行之前的 1 天或当前行之前的 6 天,具体取决于是否包含当前行。
关于sql - 按日期滚动求和的窗口函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64341909/