2016-03-30 3 views
2

Привет Я хочу сделать динамические временные ряды, используя generate_series в Postgresql.Postgresql generate_series динамический интервал

К примеру, у меня есть набор случайного списка дат:

cleaning date 
2015-03-01 00:00 
2015-05-31 00:00 
2015-06-13 00:00 

, и я хочу, чтобы динамически разделить период даты этой очищающей датой.

Результат будет выглядеть следующим образом:

start date   end date 
0000-00-00 00:00 2015-03-01 00:00 
2015-03-01 00:00 2015-05-31 00:00 
2015-05-31 00:00 2015-06-13 00:00 
2015-06-13 00:00 (current_timestamp) 

У меня нет ни малейшего представления о том, как я установил динамический интервал в generate_series ... Это возможно благодаря generate_series?

+2

'0000-00-00 00: 00' является недействительным Дата –

ответ

0

Я действительно не вижу смысла использовать generate_series.

Чтобы получить результат, который вы предложили, вы можете использовать ROW_NUMBER и автообъединение:

CREATE TABLE tab(cleaning timestamp); 

INSERT INTO tab(cleaning) 
VALUES ('2015-03-01 00:00'), ('2015-05-31 00:00'), ('2015-06-13 00:00'); 

Основной запрос:

WITH cte AS 
(
    SELECT cleaning, ROW_NUMBER() OVER(ORDER BY cleaning) AS rn 
    FROM tab 
) 
SELECT COALESCE(c1.cleaning,'0001-01-01'::timestamp) AS start_date, 
     COALESCE(c2.cleaning,CURRENT_TIMESTAMP) AS end_date 
FROM cte c1 
FULL JOIN cte c2 
    ON c1.rn = c2.rn-1 
ORDER BY start_date; 

SqlFiddleDemo

Выход:

╔═══════════════════════════╦═════════════════════════╗ 
║  start_date   ║  end_date   ║ 
╠═══════════════════════════╬═════════════════════════╣ 
║ January, 01 0001 00:00:00 ║ March, 01 2015 00:00:00 ║ 
║ March, 01 2015 00:00:00 ║ May, 31 2015 00:00:00 ║ 
║ May,  31 2015 00:00:00 ║ June, 13 2015 00:00:00 ║ 
║ June, 13 2015 00:00:00 ║ March, 30 2016 11:03:38 ║ 
╚═══════════════════════════╩═════════════════════════╝ 

EDIT:

Другая возможность заключается в использовании LAG/LEAD оконных функций:

SELECT COALESCE(LAG(cleaning) OVER(ORDER BY cleaning), '0001-01-01'::timestamp) 
     AS start_date 
     ,cleaning AS end_date 
FROM tab 
UNION ALL 
SELECT MAX(cleaning), CURRENT_TIMESTAMP 
FROM tab 
ORDER BY start_date; 

SqlFiddleDemo2

Смежные вопросы