SQL - 重复最后一个已知值,直到昨天
Posted
技术标签:
【中文标题】SQL - 重复最后一个已知值,直到昨天【英文标题】:SQL - Repeat the last known value until yesterday 【发布时间】:2019-02-01 16:37:17 【问题描述】:我有一个包含日期、ID 和值的表格。对于某些 ID,我没有到昨天的值。我需要重复每个 ID 的最后一个已知值,直到昨天它为 NULL。 我已经使用 CTE 来填充 2 个非 NULL 值之间的 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 |
+-----------+-----+-------+
感谢您的帮助。
【问题讨论】:
能否添加您目前尝试过的代码?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") ;
请使用此查询编辑您的问题
@APH,这是我使用的代码。但这仅适用于填充两个日期之间的缺失值。有边界时它不起作用。
@JonScott 刚刚做了。
【参考方案1】:
在提供的查询中,当日期是 id
的最后一个可用日期时,lead
(“NextValue”)返回的下一个日期将是 NULL
。当“NextValue”为NULL
时,要一直填写到昨天,您需要更改您的ISNULL
,以便将NULL
替换为昨天的日期。
您当前拥有它的方式,当“NextValue”为空时,它会返回原始日期,这意味着对于任何id
的系列中的最后一个值,它只会加入您的日历表以获取确切的日期ig.date
原始条目的值。
例如,对于ID = 111
,最后日期是 19/1/27,因此该行的“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
替换为返回您希望它填充的日期的函数;即昨天)。
【讨论】:
谢谢@APH 由于我对 CTE 还很陌生,能否请您插入修改内容?我理解您的评论,但不知道如何解决。 您的 CTE 对我来说看起来不错 - 实际上只是需要更新日历表的联接。我会在答案中添加一些代码。以上是关于SQL - 重复最后一个已知值,直到昨天的主要内容,如果未能解决你的问题,请参考以下文章