SQL Server 当SQL中有多个连续的空值时,如何根据前几个月的值填充空值

8ehkhllq  于 2023-01-16  发布在  其他
关注(0)|答案(4)|浏览(222)

下面是输入表:
| 月份|价值|
| - ------|- ------|
| 1个|二百|
| 第二章|- -|
| 三个|- -|
| 四个|三百|
| 五个|- -|

预期产出:

| 月份|价值|
| - ------|- ------|
| 1个|二百|
| 第二章|二百|
| 三个|二百|
| 四个|三百|
| 五个|三百|
我确实尝试在SQL中使用LAG函数,结果我能够填充立即NULL值的值,在上面的示例中为第2个月,但下个月(第3个月)仍具有NULL值

uqcuzwp8

uqcuzwp81#

可以使用LEAD函数构建查询,将数据转换为范围,如下所示:
| 从_月|至_月|价值|
| - ------|- ------|- ------|
| 1个|三个|二百|
| 四个|五个|三百|
然后使用update join语句更新表,如下所示:

Update table_name Set Value = D.Value
From table_name T Join
(
  Select Month As from_month, 
       Lead(Month, 1, (select max(month) from table_name) +1)
       Over(Order By Month) -1 As to_month,
       Value
  From table_name 
  Where Value Is Not Null
) D
On T.month Between D.from_month And D.to_month
Where T.Value Is Null;

See demo

nqwrtyyt

nqwrtyyt2#

您可以通过使用以下内容创建分区来模拟LAST_VALUE函数以忽略空值:

  • 一个非空值
  • 后面的空值(不包括下一个非空值)

然后将空值更新为每个分区的最大值。

WITH cte AS (
    SELECT *, COUNT(Value) OVER(ORDER BY Month) AS partitions
    FROM tab
), cte2 AS (
    SELECT Month, MAX(Value) OVER(PARTITION BY partitions) AS Value 
    FROM cte
)
UPDATE tab
SET tab.Value = cte2.Value
FROM cte2
WHERE tab.Month = cte2.Month;

检查here演示。

olhwl3o2

olhwl3o23#

您可以使用简单的关联和可更新的表表达式来完成此操作:

update u set value = v
from (
    select *, 
        (select top(1) value 
        from t t2 where t2.month < t.month 
            and t2.value is not null 
            order by month desc
        )v
    from t
    where t.value is null
)u;
yv5phkfx

yv5phkfx4#

如果您不喜欢老式的解决方案,您也可以一次完成:

with testdata as (
    select *
    from    (
        values (1, 200), (2, 50), (3,NULL), (4,300), (5, NULL), (6, NULL), (7, 10)
        ) x (mon, val)
    )
select mon, val AS orig
,   cast(substring(maxvalue2, 31, 30) as int) AS new
FROM (
        SELECT  MAX(CAST(mon AS BINARY(30)) + CAST(val AS BINARY(30))) OVER(ORDER BY mon) AS maxValue2
        ,   *
        FROM    testdata
    ) x

相关问题