sql-server - 更新表但跳过某些具有特定条件的行
问题描述
我有一个名为的表body_scan
,如下所示:
body_no tag
--------------------
1 noscan
2 noscan
3 missing
4 noscan
5 missing
我还有一个列表,我可以像这样加载到临时表中
tag_no
------
aaa
bbb
ccc
我需要做的是body_scan
用临时表中的标签号更新表。
您会注意到 temp 表中只有 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
解决方案
首先,您需要通过向其中添加一个字段来保留数据的输入文件顺序(请注意,一些 ETL 工具会并行插入数据,这会使事情变得混乱,因此您甚至可能需要将此列添加到文件中)identity
temp_table
完成后,您需要在 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;
(有六种方法可以编写最终语句,但我更喜欢这种方式,因为您可以在子选择中看到您正在更新的数据集)
推荐阅读
- compare - 仅从一个列表中删除重复项
- flutter - 如何限制 `Scaffold` 的宽度和高度(适用于 Web 和桌面)
- rust - cargo rust 构建脚本 - 打印命令输出
- android - ApplyParsedPerms:lsetfilecon of /system/lost+found 到 u:object_r:system_set_metadata_recursive:一些更改失败
- python - 有没有更有效的方法来找到这个对象的轮廓并填充python中的空白?
- python-3.8 - 无法更新字典
- php - 从今天开始循环以从一组模板生成班次/轮班列表
- c# - 设置 resx 文件的自定义工具命名空间属性时,IStringLocalizer 不起作用
- go - 实现 Go 接口时如何处理重复性和灵活性?
- javascript - 我不明白为什么“.map”在这个变量中没有定义