Рассмотрим следующую структуру таблицы:
CREATE TABLE tb_log
(
id INTEGER PRIMARY KEY,
moment DATE,
old INTEGER,
actual INTEGER
);
Содержит данные:
INSERT INTO
tb_log ( id, moment, old, actual )
VALUES
( 1, '2018-06-19', 10, 20 ),
( 2, '2018-06-21', 20, 30 ),
( 3, '2018-06-25', 30, 40 );
Я пытаюсь получить от tb_log
период (начальная и конечная даты), в котором действовало значение.
Trial # 1 - Использование функции lag()
:
SELECT
lag( moment ) OVER (ORDER BY moment) date_start,
moment AS date_end,
old AS period_value
FROM
tb_log;
, который возвращает следующие данные:
| date_start | date_end | period_value |
|------------|------------|--------------|
| (null) | 2018-06-19 | 10 |
| 2018-06-19 | 2018-06-21 | 20 |
| 2018-06-21 | 2018-06-25 | 30 |
Trial # 2 - Использование функции lead()
:
SELECT
moment AS date_start,
lead( moment ) OVER (ORDER BY moment) date_end,
actual AS period_value
FROM
tb_log;
, который возвращает следующие данные:
| date_start | date_end | period_value |
|------------|------------|--------------|
| 2018-06-19 | 2018-06-21 | 20 |
| 2018-06-21 | 2018-06-25 | 30 |
| 2018-06-25 | (null) | 40 |
SQLFiddle.com
Есть ли какой-нибудь трюк, использующий Window Functions
, чтобы вернуть что-то вроде этого:
| date_start | date_end | period_value |
|------------|------------|--------------|
| (null) | 2018-06-19 | 10 |
| 2018-06-19 | 2018-06-21 | 20 |
| 2018-06-21 | 2018-06-25 | 30 |
| 2018-06-25 | (null) | 40 |
Есть идеи?