替换空值为前一行的数值。

huangapple go评论58阅读模式
英文:

Replace null value with value from the previous row

问题

无法解决这个问题,因为列:ID 不是唯一的。

我不知道如何用前一行的值替换空值。

原样

ID NAME
001 NULL
001 A
001 NULL
001 NULL
001 B
001 NULL

期望

ID NAME
001 NULL
001 A
001 A
001 A
001 B
001 B
英文:

I can not to solve in this problem because column : ID is not unique.

I don't know to replace null value with value from the previous row.

AS IS

ID NAME
001 NULL
001 A
001 NULL
001 NULL
001 B
001 NULL

TO BE

ID NAME
001 NULL
001 A
001 A
001 A
001 B
001 B

答案1

得分: 1

如@siggemannen在评论中提到的,您需要为每个ID提供一个日期/时间戳或唯一标识以使其成为可能。

假设您有一个称为rn_id的唯一标识符,窗口函数MAX()与范围子句可以帮助您,只有当NAME按字母顺序排序时才能使用:

select id, max(NAME) over ( partition by ID order by rn_id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as NAME 
from mytable 

结果:

id	|NAME
----|----
1	|null
1	|A
1	|A
1	|A
1	|B
1	|B

如果不按字母顺序排序,那么我们将需要使用两个窗口函数:

IIF()函数将在值存在时返回1,否则将返回零。窗口化的总和将显示递增的运行总和,这将为值及其后面的null创建一个分组。

然后first_value()将捕获每个组的最后一个非null值:

with cte as (
  SELECT 
      ID,
      rn_id,
      NAME,
      SUM(IIF(NAME IS NULL, 0,1)) OVER (partition by ID ORDER BY rn_id ASC) AS grp
    FROM 
      mytable
)
select id, First_value(NAME) over ( partition by ID, grp order by rn_id) as NAME_
from cte

演示在此

英文:

As @siggemannen mentioned in the comments, you need a date/timestamp or a unique id per ID to make it possible.

Assuming you have a unique id per ID called rn_id, the window function MAX() with a range clause can help you only if NAME are ordered alphabetically :

select id, max(NAME) over ( partition by ID order by rn_id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as NAME 
from mytable 

Result :

id NAME
1 null
1 A
1 A
1 A
1 B
1 B

Demo here

If not ordered alphabetically then we will need to use two window functions :

The IIF() function will return 1 when a value is present, otherwise it will return zero. The windowed sum will show the running total increasing, which will create a grouping for a value and it's following nulls.

Then first_value() will catch the last non null value per group :

with cte as (
  SELECT 
      ID,
      rn_id,
      NAME,
      SUM(IIF(NAME IS NULL, 0,1)) OVER (partition by ID ORDER BY rn_id ASC) AS grp
    FROM 
      mytable
)
select id, First_value(NAME) over ( partition by ID, grp order by rn_id) as NAME_
from cte

Demo here

huangapple
  • 本文由 发表于 2023年5月25日 17:44:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/76330932.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定