SQL Server更新表但跳过具有特定条件的某些行

时间:2018-06-10 22:50:30

标签: sql-server join sql-server-2012

我有一个名为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

2 个答案:

答案 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
相关问题