此答案基于Gordon Linoff's idea,
但有一些调整:
FILTER is not implemented for pure window functions 类似于 Postgresql 11 中的 Lead() 或 lag()(目前)。所以使用WHERE fruit_bought='orange'作为整个内部SELECT的条件。
要保证选择具有最后日期的行,请使用LEAD(date, 1, '-infinity')。这使得next_date 的默认值等于-infinity 时间戳。因此date >= next_date - interval '10 day' 将在最后一个日期为 TRUE。
-
让我们将 10 天内的行称为一个集群。要仅从最后一个集群中选择行,
计算一个累积总和,计算 cond 为 FALSE 的次数(因为 FALSE 值分隔集群):
SUM(CASE WHEN cond IS TRUE THEN 0 ELSE 1 END) OVER (ORDER BY date DESC) AS cluster_num
只选择cluster_num等于0的行。因为我们ORDER BY date DESC,所以第0个簇是最后一个簇。
SELECT *
FROM (
SELECT *, SUM(CASE WHEN cond IS TRUE THEN 0 ELSE 1 END) OVER (ORDER BY date DESC) AS cluster_num
FROM (
SELECT *, date >= next_date - interval '10 day' AS cond
FROM (
SELECT id, fruit_bought, date,
LEAD(date, 1, '-infinity')
OVER (PARTITION BY fruit_bought ORDER BY date) AS next_date
FROM fruits
WHERE fruit_bought='orange'
-- restrict date here to specify an "initial date"
AND date <= '2018-04-01'
) t1
) t2
) t3
WHERE cond AND cluster_num = 0
ORDER BY date ASC
产量
| id | fruit_bought | date | next_date | cond | cluster_num |
|----+--------------+------------+------------+------+-------------|
| 3 | orange | 2018-03-07 | 2018-03-15 | t | 0 |
| 4 | orange | 2018-03-15 | 2018-03-20 | t | 0 |
| 6 | orange | 2018-03-20 | -infinity | t | 0 |
设置:
CREATE TABLE fruits (
fruitid INT PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
id INT,
fruit_bought TEXT,
quantity INT,
date DATE);
INSERT INTO fruits (id, fruit_bought, quantity, date)
VALUES (1,'orange',100,'2018-01-10')
, (2,'apple',50,'2018-02-05')
, (3,'orange',75,'2018-03-07')
, (4,'orange',200,'2018-03-15')
, (5,'apple',10,'2018-03-17')
, (6,'orange',20,'2018-03-20')
, (7,'orange',20,'2018-01-09');