REPLACE * NULL 的最后一个已知值的函数
Function to REPLACE* last previous known value for NULL
我想用该列的最后一个给定值填充 NULL 值。一小部分数据样本:
2021-08-15 Bulgaria 1081636
2021-08-16 Bulgaria 1084693
2021-08-17 Bulgaria 1089066
2021-08-18 Bulgaria NULL
2021-08-19 Bulgaria NULL
在此示例中,NULL 值应为 1089066,直到我到达下一个非 NULL 值。
我尝试了response中给出的答案,但没有成功。任何帮助将不胜感激,谢谢!
编辑:抱歉,我在尝试 return 最后一个值时分心了,我忘记了我的最终目标,即用以前的已知值替换 NULL 值。
因此查询应该是
UPDATE covid_data
SET people_vaccinated = ISNULL(?)
假设您拥有的数字一直在增加,您可以在 window:
上使用 MAX 聚合
SELECT dt
, country
, cnt
, MAX(cnt) OVER (PARTITION BY country ORDER BY dt)
FROM #data
如果数字可能会减少,查询会变得有点复杂,因为我们需要首先将具有空值的行标记为与最后一个没有空值的行属于同一组:
SELECT dt
, country
, cnt
, SUM(cnt) OVER (PARTITION BY country, partition)
FROM (
SELECT country
, dt
, cnt
, SUM(CASE WHEN cnt IS NULL THEN 0 ELSE 1 END) OVER (PARTITION BY country ORDER BY dt) AS partition
FROM #data
) AS d
ORDER BY dt
Here's a working demo on dbfiddle,它returns相同的数据,数量不断增加,但是如果将08-17的数字更改为低于08-16的数字,您会看到MAX (...) 产生错误结果的方法。
在许多数据集中,对基础数据集中数据的行为做出假设是不正确的,如果您的目标只是填补数据集中可能出现 mid-way 的空白,那么答案是post 你提到的 A:sql server nulls duplicate last known value in table 仍然是最好的解决方案之一,这里是一个改编:
SELECT dt
, country
, cnt
, ISNULL(source.cnt, excludeNulls.LastCnt)
FROM #data source
OUTER APPLY ( SELECT TOP 1 cnt as LastCnt
FROM #data
WHERE dt < source.dt
AND cnt IS NOT NULL
ORDER BY dt desc) ExcludeNulls
ORDER BY dt
MAX
和 LAST_VALUE
会给你一个关于 entire 记录集的值,如果你具有 2021-08-19
的值。在这种情况下,将使用最后一个值来填补空白,而不是之前的 non-null 值。
当我们需要填补 part-way 结果中出现的空白时,我们需要对 window 查询应用过滤器,TOP 1 ... ORDER BY
使我们能够过滤和排序在与我们要捕获的字段完全不同的字段上,但也意味着我们可以显示非数字字段的最后一个值,请参见 fiddle 其他几个示例:https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=372285d29f97dbb9663e8552af6fb7a2
我想用该列的最后一个给定值填充 NULL 值。一小部分数据样本:
2021-08-15 Bulgaria 1081636
2021-08-16 Bulgaria 1084693
2021-08-17 Bulgaria 1089066
2021-08-18 Bulgaria NULL
2021-08-19 Bulgaria NULL
在此示例中,NULL 值应为 1089066,直到我到达下一个非 NULL 值。
我尝试了response中给出的答案,但没有成功。任何帮助将不胜感激,谢谢!
编辑:抱歉,我在尝试 return 最后一个值时分心了,我忘记了我的最终目标,即用以前的已知值替换 NULL 值。
因此查询应该是
UPDATE covid_data
SET people_vaccinated = ISNULL(?)
假设您拥有的数字一直在增加,您可以在 window:
上使用 MAX 聚合SELECT dt
, country
, cnt
, MAX(cnt) OVER (PARTITION BY country ORDER BY dt)
FROM #data
如果数字可能会减少,查询会变得有点复杂,因为我们需要首先将具有空值的行标记为与最后一个没有空值的行属于同一组:
SELECT dt
, country
, cnt
, SUM(cnt) OVER (PARTITION BY country, partition)
FROM (
SELECT country
, dt
, cnt
, SUM(CASE WHEN cnt IS NULL THEN 0 ELSE 1 END) OVER (PARTITION BY country ORDER BY dt) AS partition
FROM #data
) AS d
ORDER BY dt
Here's a working demo on dbfiddle,它returns相同的数据,数量不断增加,但是如果将08-17的数字更改为低于08-16的数字,您会看到MAX (...) 产生错误结果的方法。
在许多数据集中,对基础数据集中数据的行为做出假设是不正确的,如果您的目标只是填补数据集中可能出现 mid-way 的空白,那么答案是post 你提到的 A:sql server nulls duplicate last known value in table 仍然是最好的解决方案之一,这里是一个改编:
SELECT dt
, country
, cnt
, ISNULL(source.cnt, excludeNulls.LastCnt)
FROM #data source
OUTER APPLY ( SELECT TOP 1 cnt as LastCnt
FROM #data
WHERE dt < source.dt
AND cnt IS NOT NULL
ORDER BY dt desc) ExcludeNulls
ORDER BY dt
MAX
和 LAST_VALUE
会给你一个关于 entire 记录集的值,如果你具有 2021-08-19
的值。在这种情况下,将使用最后一个值来填补空白,而不是之前的 non-null 值。
当我们需要填补 part-way 结果中出现的空白时,我们需要对 window 查询应用过滤器,TOP 1 ... ORDER BY
使我们能够过滤和排序在与我们要捕获的字段完全不同的字段上,但也意味着我们可以显示非数字字段的最后一个值,请参见 fiddle 其他几个示例:https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=372285d29f97dbb9663e8552af6fb7a2