我有一个名为body_scan
的表,如下所示:
body_no tag
--------------------
1 noscan
2 noscan
3 missing
4 noscan
5 missing
我还有一个列表可以加载到临时表中,如此
tag_no
------
aaa
bbb
ccc
我需要做的是使用临时表中的标签号更新body_scan
表。
您会注意到临时表中只有3个标签,而body_scan表中只有5个标签。我需要更新标签值" noscan"使用临时表中的值并保留缺失值。
临时表中标签的顺序与body_no
表中body_scan
的顺序相同。
是的,我确实考虑过row_number()
功能。但我并不是100%确定如何正确定义连接..
我该如何做到这一点?
期望的结果是:
body_no tag
-------------------
1 aaa
2 bbb
3 missing
4 ccc
5 missing
答案 0 :(得分:1)
首先,您需要通过向identity
添加temp_table
字段来保留输入文件数据顺序(请注意,某些ETL工具并行插入数据并且搞砸了,所以你甚至可能需要将这个列添加到文件中)
完成后,您需要在body_scan中生成一个可以加入的密钥。这只是现有表格的ROW_NUMBER()
,不包括缺失的行
这会在temp_table
SELECT
body_no,
ROW_NUMBER() OVER (ORDER BY body_no) RN
FROM body_scan
WHERE tag<> 'missing';
这会加入临时表(假设您的序数列称为RowID)
SELECT T1.body_no, T1.tag, T1.RN, T2.tag_no
FROM
(
SELECT
body_no,tag,
ROW_NUMBER() OVER (ORDER BY body_no) RN
FROM body_scan
WHERE tag<> 'missing'
) T1
INNER JOIN
temp_table T2
ON T1.RN=T2.RowID;
将其更新回表:
UPDATE TGT
SET tag=SRC.tag_no
FROM body_scan TGT
INNER JOIN
(
SELECT T1.body_no, T2.tag_no
FROM
(
SELECT
body_no,tag,
ROW_NUMBER() OVER (ORDER BY body_no) RN
FROM body_scan
WHERE tag<> 'missing'
) T1
INNER JOIN
temp_table T2
ON T1.RN=T2.RowID
) SRC
ON SRC.body_no=TGT.body_no;
(有六种方法可以编写最终语句,但我更喜欢这种方式,因为您可以在子选择中看到要更新的数据集)
答案 1 :(得分:1)
我无法理解你的解释和命令讨论。我锻炼(在SQL 2012中)来实现你的OUTPUT表。如,
update a
set a.tag = t.tag
from (
select m.*, ROW_NUMBER() over(partition by m.tag order by m.rn)trn from(
select *, row_number() over(partition by (select null) order by (select null)) rn from body_scan --set order what the order of actual table's order
) m --set row number for noscan rows
) a
join(
select *, ROW_NUMBER() over(order by (select null)) rn from #temp --set order what the order of actual table order
) t
on a.trn = t.rn and a.tag <> 'missing' -- join to noscan rows using row numbers
输出:
body_no tag
--------------
1 aaa
2 bbb
3 missing
4 ccc
5 missing