Oracle SQL,用最接近的非缺失值填充缺失值

Oracle SQL, fill missing value with the closest non-missing

我有一个数据集,我想用最接近的非缺失值填充其中的缺失值。我在 this 问题的答案中找到了两个优雅的解决方案,但我不明白为什么它们对我不起作用。

Table:

create table Tab1(data date, V1 number);
insert into Tab1 values (date '2000-01-01', 1);
insert into Tab1 values (date '2000-02-01', 1);
insert into Tab1 values (date '2000-03-01', 1);
insert into Tab1 values (date '2000-04-01', 1);
insert into Tab1 values (date '2000-05-01', NULL);
insert into Tab1 values (date '2000-06-01', NULL);
insert into Tab1 values (date '2000-03-01', 2);
insert into Tab1 values (date '2000-04-01', 2);
insert into Tab1 values (date '2000-05-01', NULL);
insert into Tab1 values (date '2000-06-01', NULL);
select * from Tab1;

DATA       V1
2000-01-01  1
2000-02-01  1
2000-03-01  1
2000-04-01  1
2000-05-01  
2000-06-01  
2000-03-01  2
2000-04-01  2
2000-05-01  
2000-06-01  

尝试 #1:

select A.*, 
    (case when V1 is null then lag(V1 ignore nulls)  
               over (partition by V1 order by V1, data) 
          else V1 
          end) V2
 from Tab1 A;

尝试 #2:

select A.*, 
    (case when V1 is null 
               then last_value(V1 ignore nulls)
               over (partition by V1 order by data 
               range between unbounded preceding and 1 preceding)  
          else V1 
          end) V2
 from Tab1 A;

两者都给我相同的不需要的结果:

DATA       V1   V2
2000-01-01  1   1
2000-02-01  1   1
2000-03-01  1   1
2000-04-01  1   1
2000-03-01  2   2
2000-04-01  2   2
2000-05-01      
2000-05-01      
2000-06-01      

我做错了什么?

你的第一个版本应该可以工作,稍作调整:

select A.*, 
       coalesce(V1, lag(V1 ignore nulls)  over (order by data)) V2
from Tab1 A;

调整是从 lag() 中删除 partition by v1coalesce() 只是我对更简单表达式的偏爱。

同样的调整也适用于第二个版本。

您的版本不起作用,因为 lag() 值必须来自同一分区(或者是 null)。当您有 partition by v1 时,您实际上是在确保 v1 与当前行中的值相同。

您好,或者您可以参考我的下文尝试手动创建忽略空值的解决方案。谢谢

  1. 您需要使用 0/1 列来表示 Null/Non-Null 数据
  2. 然后创建累积摘要列以计算步骤 1 中的指标编号。-现在您可以看到数据看起来已经按 non_Null 数据分组。
  3. 作为最后一步,请使用 Max 函数组通过累加和(在步骤 2 中)将数据(这里是 amont)填充到空项目中。