假设您有以下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');
如何将这些日期汇总到连续日期范围(无间隙范围)?如:
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
这是我到目前为止所提出的,但我只能这样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;
答案 0 :(得分:8)
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;
使用窗口函数row_number()
按时间顺序计算正在运行的无间隙数字 - 除非您的reserved_days_id
恰好是无间隙且按时间顺序排列,通常为不案例。
从每行reserved_date
中扣除(转换为integer
后)。连续几天结束时的日期值grp
相同 - 除了形成群组之外没有其他目的或意义。
在外部查询中聚合。瞧。
类似案例: