SQL - повторять последнее известное значение до вчерашнего дня - PullRequest
0 голосов
/ 01 февраля 2019

У меня есть таблица с датой, идентификатором и значением.Для какого-то удостоверения у меня нет значения до вчерашнего дня.Мне нужно повторить последнее известное значение для каждого идентификатора до вчерашнего дня, где он равен NULL.Я уже использовал CTE для заполнения значений NULL между 2 значениями, отличными от NULL, но он не работает до вчерашнего дня.Данные выглядят так:

+-----------+-----+-------+
|   Date    | ID  | Value |
+-----------+-----+-------+
| 1/25/2019 | 111 |    50 |
| 1/26/2019 | 111 |   100 |
| 1/27/2019 | 111 |   150 |
| 1/25/2019 | 222 |   500 |
| 1/26/2019 | 222 |  1000 |
| 1/27/2019 | 222 |  1500 |
+-----------+-----+-------+

Я попробовал следующий код, но потерпел неудачу:

WITH CAwithnext AS (
  SELECT
    *,
    LEAD("date") OVER (PARTITION BY "id" ORDER BY "date") AS "NextValue"
  FROM "transform_data_1"
  )
SELECT
    c."Date",
    ig."id",
    ig."value"
FROM "calendar_from_2015_to_2025" AS c
JOIN "CAwithnext" AS ig
    ON c."Date" BETWEEN ig."date" AND ISNULL(DATEADD(day,-1,ig."NextValue"),ig."date")
;

Вот ожидаемый результат:

+-----------+-----+-------+
|   Date    | ID  | Value |
+-----------+-----+-------+
| 1/25/2019 | 111 |    50 |
| 1/26/2019 | 111 |   100 |
| 1/27/2019 | 111 |   150 |
| 1/28/2019 | 111 |   150 |
| 1/29/2019 | 111 |   150 |
| 1/30/2019 | 111 |   150 |
| 1/31/2019 | 111 |   150 |
| 1/25/2019 | 222 |   500 |
| 1/26/2019 | 222 |  1000 |
| 1/27/2019 | 222 |  1500 |
| 1/28/2019 | 222 |  1500 |
| 1/29/2019 | 222 |  1500 |
| 1/30/2019 | 222 |  1500 |
| 1/31/2019 | 222 |  1500 |
+-----------+-----+-------+

Спасибоза помощь.

1 Ответ

0 голосов
/ 01 февраля 2019

В предоставленном запросе, когда дата является последней доступной датой для id, следующая дата, возвращаемая вашим lead ("NextValue"), будет NULL.Чтобы заполнить весь путь до вчерашнего дня, когда «NextValue» равно NULL, вам необходимо изменить ISNULL, чтобы он заменял NULL на вчерашнюю дату.

То, как у вас это есть,когда «NextValue» равно нулю, вместо этого возвращается исходная дата, что означает, что для последнего значения в любой серии id он будет присоединяться к вашей календарной таблице только для точного значения ig.date исходной записи.

Например, для ID = 111 последняя дата - 27.01.19, поэтому «NextValue» для этой строки будет NULL.Если вы выбираете из своего CTE напрямую, вы должны увидеть что-то вроде:

ID    Date    NextValue
111   1/26/18 1/27/19
111   1/27/19 NULL

Когда вы присоединяетесь к своему календарю, ваш ISNULL эффективно превращает ваши критерии объединения в on c.Date between 1/27/19 and isnull(NULL, 1/27/19) или on c.Date between 1/27/19 and 1/27/19, чтоВот почему вы получаете только один ряд для последней записи.

Чтобы решить, измените последнюю строку вашего запроса с:

ISNULL(DATEADD(day,-1,ig."NextValue"),ig."date")

на

ISNULL(DATEADD(day,-1,ig."NextValue"),DATEADD(day,-1,GetDate()))

или

DATEADD(day,-1,ISNULL(ig."NextValue", GetDate()))

(в основном,замените ig.date на функцию, которая возвращает дату, до которой вы хотите ее заполнить; т.е. вчера).

...