[英]How do I populate the Null Values based on Previous months value, when there are multiple continues Null values in SQL
Below is the input table:下面是输入表:
Month![]() |
Value![]() |
---|---|
1 ![]() |
200 ![]() |
2 ![]() |
- ![]() |
3 ![]() |
- ![]() |
4 ![]() |
300 ![]() |
5 ![]() |
- ![]() |
Expected Output:预计 Output:
Month![]() |
Value![]() |
---|---|
1 ![]() |
200 ![]() |
2 ![]() |
200 ![]() |
3 ![]() |
200 ![]() |
4 ![]() |
300 ![]() |
5 ![]() |
300 ![]() |
I did try using LAG function in SQL, as a result I was able to populate value for the immediate NULL values which is Month 2 in above case but next month which is Month 3 was still having Null values我确实尝试在 SQL 中使用 LAG function,结果我能够填充即时 NULL 值的值,在上述情况下是第 2 个月,但下个月是第 3 个月仍然有 Null 值
You can build a query using the LEAD
function to convert your data into ranges as the following:您可以使用
LEAD
function 构建查询,将数据转换为范围,如下所示:
from_month![]() |
to_month ![]() |
Value![]() |
---|---|---|
1 ![]() |
3 ![]() |
200 ![]() |
4 ![]() |
5 ![]() |
300 ![]() |
Then use the update join
statement to update your table as the following:然后使用
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;
You can emulate the LAST_VALUE
function to ignore nulls by creating partitions with:您可以通过创建分区来模拟
LAST_VALUE
function 以忽略空值:
then updating null values to the max for each partition.然后将 null 值更新为每个分区的最大值。
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;
You can do this with a simple correlation and an updatable table expression:您可以使用简单的关联和可更新的表表达式来做到这一点:
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;
If you don't like the old hat solutions you can do it in one pass too:如果您不喜欢旧帽子解决方案,您也可以一次性完成:
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.