Lin*_*nas 6 sql postgresql time-series aggregate-functions window-functions
假设您有以下PostgreSQL稀疏表列出预订日期:
CREATE TABLE reserved_dates (
reserved_days_id SERIAL NOT NULL,
reserved_date DATE NOT NULL
);
INSERT INTO reserved_dates (reserved_date) VALUES
('2014-10-11'),
('2014-10-12'),
('2014-10-13'),
-- gap
('2014-10-15'),
('2014-10-16'),
-- gap
('2014-10-18'),
-- gap
('2014-10-20'),
('2014-10-21');
Run Code Online (Sandbox Code Playgroud)
如何将这些日期汇总到连续日期范围(没有间隙的范围)?如:
start_date | end_date
------------+------------
2014-10-11 | 2014-10-13
2014-10-15 | 2014-10-16
2014-10-18 | 2014-10-18
2014-10-20 | 2014-10-21
Run Code Online (Sandbox Code Playgroud)
这是我到目前为止所提出的,但我只能start_date这样:
WITH reserved_date_ranges AS (
SELECT reserved_date,
reserved_date
- LAG(reserved_date) OVER (ORDER BY reserved_date) AS difference
FROM reserved_dates
)
SELECT *
FROM reserved_date_ranges
WHERE difference > 1 OR difference IS NULL;
Run Code Online (Sandbox Code Playgroud)
SELECT min(reserved_date) AS start_date
, max(reserved_date) AS end_date
FROM (
SELECT reserved_date
, reserved_date - row_number() OVER (ORDER BY reserved_date)::int AS grp
FROM reserved_dates
) sub
GROUP BY grp
ORDER BY grp;
Run Code Online (Sandbox Code Playgroud)
使用窗函数按时间顺序计算一个正在运行的无间隙数row_number()- 除非你reserved_days_id恰好是无间隙且按时间顺序排列,通常不是这种情况.
从reserved_date每一行中扣除(转换后integer).连续几天以相同的日期值结束grp- 除了形成组之外没有其他目的或意义.
在外部查询中聚合.瞧.
类似案例: