汇总连续的日期范围

时间:2014-10-20 23:45:25

标签: 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');

如何将这些日期汇总到连续日期范围(无间隙范围)?如:

 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;

1 个答案:

答案 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;
  1. 使用窗口函数row_number()按时间顺序计算正在运行的无间隙数字 - 除非您的reserved_days_id恰好是无间隙且按时间顺序排列,通常为案例。

  2. 从每行reserved_date中扣除(转换为integer后)。连续几天结束时的日期值grp相同 - 除了形成群组之外没有其他目的或意义。

  3. 在外部查询中聚合。瞧。

  4. SQL Fiddle.

    类似案例: