【发布时间】:2019-07-08 14:06:28
【问题描述】:
一个初学者的问题。
前提:我知道这里的关键问题是 SQL 表中没有固有顺序,因此为了向表中“添加”一列,我必须指定一些键匹配。但是,我正在寻找一个优雅的解决方案。
问题:
我想用通过窗口函数获得的V1 的转换替换列V1 的值(我用最接近的已知值V1 填充NULL 值,按data 排序)。
示例数据集(请注意我没有识别行的键):
create table Tab1(data date, V1 number, val number);
insert into Tab1 values (date '2000-01-01', 1, 100);
insert into Tab1 values (date '2000-02-01', 1, 110);
insert into Tab1 values (date '2000-03-01', 1, 100);
insert into Tab1 values (date '2000-03-01', 1, 130);
insert into Tab1 values (date '2000-05-01', NULL, 100);
insert into Tab1 values (date '2000-06-01', NULL, 100);
insert into Tab1 values (date '2000-03-01', 2, 110);
insert into Tab1 values (date '2000-03-01', 2, 105);
insert into Tab1 values (date '2000-04-01', 2, 190);
insert into Tab1 values (date '2000-05-01', NULL, 200);
insert into Tab1 values (date '2000-06-01', NULL, 150);
select * from Tab1;
DATA V1 val
2000-01-01 1 100
2000-02-01 1 110
2000-03-01 1 100
2000-03-01 1 130
2000-04-01 1 100
2000-05-01 100
2000-06-01 100
2000-03-01 2 110
2000-03-01 2 105
2000-04-01 2 190
2000-05-01 200
2000-06-01 150
我想避免像在
中那样创建第二个表 create table Tab2 as
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;
实际上,窗口功能仍然没有做我想要的,但这是一个单独的问题(如果你有解决方案,非常欢迎)。最后,我想要的是以下内容,其中 V1 被其版本替换,空值被最接近的非缺失值替换:
DATA V1 val
2000-01-01 1 100
2000-02-01 1 110
2000-03-01 1 100
2000-03-01 1 130
2000-04-01 1 100
2000-05-01 1 100
2000-06-01 1 100
2000-03-01 2 110
2000-03-01 2 105
2000-04-01 2 190
2000-05-01 2 200
2000-06-01 2 150
我不能使用update,因为不允许使用 windows 函数,并且带有 windows 函数的子查询会检索多行。
同样,merge into 语句也不起作用,因为我无法给出一个 on 条件来标识要匹配的单行(data 和 V1 是不够的)。
有没有办法将V2 直接“添加”到Tab1 而无需创建新表?
【问题讨论】:
-
如何添加不足以识别行的相同值将有助于创建标识?
-
添加了样本数据和想要的结果。
标签: sql oracle sql-update window-functions