SQL 服务器 - 使用没有任何键的上一列更新列
SQL Server - Updating Columns with Previous column without Any Key
我有一个 SQL 服务器 table 有五列:
Field1, Field2,Field3,Field4,Field5
现在我从一个文件加载数据,该文件的第一行有 Field1
和 Field2
值,但只有 field3
、field4
、field5
在第二行和第三行。
我现在 table 中没有关键列。
我需要能够用第一行的值更新第二行和第三行的 field1
& field2
。
这需要重复,对于没有 Field1
和 Field2
的每一行,以及前面的行。
请提出可行的方案。
你需要一把钥匙,没办法。 SQL table没有排序,需要引入排序字段。听起来您正在处理文本文件......如果是这样,您需要添加一个整数以便您可以订购您的记录。
然后您可以结合使用合并函数(return第一个非空值)和滞后函数,例如:
;with cte as (
select
ID
,coalesce(
f1
,lag(f1, 1) over (order by id)
,lag(f1, 2) over (order by id)
) f1
,coalesce(
f2
,lag(f2, 1) over (order by id)
,lag(f2, 2) over (order by id)
) f2
,f3
,f4
,f5
from (
values
(1, 'a1', 'b1', null, null, null)
,(2, null, null, 'x1', 'y1', 'z1')
,(3, null, null, 'l1', 'm1', 'n1')
,(4, 'a2', 'b2', null, null, null)
,(5, null, null, 'x2', 'y2', 'z2')
,(6, null, null, 'l2', 'm2', 'n2')
) t(ID, f1, f2, f3, f4, f5)
)
select *
from cte
where f3 is not null
这将 return table 数据,例如:
2 a1 b1 x1 y1 z1
3 a1 b1 l1 m1 n1
5 a2 b2 x2 y2 z2
6 a2 b2 l2 m2 n2
另一种解决方案较慢,涉及相关子查询。您的示例是父行后跟两个子行,重复。无论父行之间有多少子行,这都将起作用:
drop table if exists #temp
go
select *
into #temp
from (
values
(1, 'a1', 'b1', null, null, null)
,(2, null, null, 'x1', 'y1', 'z1')
,(3, null, null, 'l1', 'm1', 'n1')
,(4, null, null, 'i1', 'j1', 'k1')
,(5, 'a2', 'b2', null, null, null)
,(6, null, null, 'x2', 'y2', 'z2')
,(7, null, null, 'l2', 'm2', 'n2')
) t(ID, f1, f2, f3, f4, f5)
update #temp
set
f1 = (select top 1 f1 from #temp where f1 is not null and t.ID>=ID order by ID)
,f2 = (select top 1 f2 from #temp where f2 is not null and t.ID>=ID order by ID)
from #temp t
select *
from #temp
where f3 is not null
order by ID
我有一个 SQL 服务器 table 有五列:
Field1, Field2,Field3,Field4,Field5
现在我从一个文件加载数据,该文件的第一行有 Field1
和 Field2
值,但只有 field3
、field4
、field5
在第二行和第三行。
我现在 table 中没有关键列。
我需要能够用第一行的值更新第二行和第三行的 field1
& field2
。
这需要重复,对于没有 Field1
和 Field2
的每一行,以及前面的行。
请提出可行的方案。
你需要一把钥匙,没办法。 SQL table没有排序,需要引入排序字段。听起来您正在处理文本文件......如果是这样,您需要添加一个整数以便您可以订购您的记录。
然后您可以结合使用合并函数(return第一个非空值)和滞后函数,例如:
;with cte as (
select
ID
,coalesce(
f1
,lag(f1, 1) over (order by id)
,lag(f1, 2) over (order by id)
) f1
,coalesce(
f2
,lag(f2, 1) over (order by id)
,lag(f2, 2) over (order by id)
) f2
,f3
,f4
,f5
from (
values
(1, 'a1', 'b1', null, null, null)
,(2, null, null, 'x1', 'y1', 'z1')
,(3, null, null, 'l1', 'm1', 'n1')
,(4, 'a2', 'b2', null, null, null)
,(5, null, null, 'x2', 'y2', 'z2')
,(6, null, null, 'l2', 'm2', 'n2')
) t(ID, f1, f2, f3, f4, f5)
)
select *
from cte
where f3 is not null
这将 return table 数据,例如:
2 a1 b1 x1 y1 z1
3 a1 b1 l1 m1 n1
5 a2 b2 x2 y2 z2
6 a2 b2 l2 m2 n2
另一种解决方案较慢,涉及相关子查询。您的示例是父行后跟两个子行,重复。无论父行之间有多少子行,这都将起作用:
drop table if exists #temp
go
select *
into #temp
from (
values
(1, 'a1', 'b1', null, null, null)
,(2, null, null, 'x1', 'y1', 'z1')
,(3, null, null, 'l1', 'm1', 'n1')
,(4, null, null, 'i1', 'j1', 'k1')
,(5, 'a2', 'b2', null, null, null)
,(6, null, null, 'x2', 'y2', 'z2')
,(7, null, null, 'l2', 'm2', 'n2')
) t(ID, f1, f2, f3, f4, f5)
update #temp
set
f1 = (select top 1 f1 from #temp where f1 is not null and t.ID>=ID order by ID)
,f2 = (select top 1 f2 from #temp where f2 is not null and t.ID>=ID order by ID)
from #temp t
select *
from #temp
where f3 is not null
order by ID