我有一个场景,我希望将一个数据表导入到我的架构中。导入和目标表上的关键字段是名为MEMBERNO
在导入之前,我检查导入表中的任何行是否具有目标表中当前存在的MEMBERNO
。如果是这样,我希望在开始导入之前将导入表上的MEMBERNO
修改为下一个可用值(一个简单的INSERT INTO targetTable SELECT * FROM importTable
)
当前通过向SELECT MAX(MEMBERNO) FROM targetTable
添加1来识别下一个可用的MEMBERNO - 我可以将此函数应用于一个SQL语句中的多个行,还是必须创建一个循环的游标?理想情况下,我想有一个UPDATE语句,其中设置的值是“移动”但我不确定这是否可能
就像......
UPDATE importTable SET MEMBERNO = nextavailablenumber
WHERE MEMBERNO IN (SELECT MEMBERNO FROM targetTable)
其中为每个UPDATE
答案 0 :(得分:2)
您甚至不需要进行更新,您可以检查并更改插入目标表中的MemberNo
全部
INSERT TargetTable (MemberNo, Column1, Column2, Column3)
SELECT MemberNo = CASE WHEN t.MemberNoExists IS NULL THEN i.MemberNo
ELSE n.NextMemberNo + ROW_NUMBER() OVER(PARTITION BY t.MemberNoExists ORDER BY i.MemberNo)
END,
i.Column1,
i.Column2,
i.Column3
FROM ImportTable i
OUTER APPLY
( SELECT TOP 1 MemberNoExists = 1
FROM TargetTable t
WHERE t.MemberNo = i.MemberNo
) t
CROSS JOIN
( SELECT NextMemberNo = MAX(MemberNo)
FROM TargetTable
) n;
当MemberNo已经存在时,子查询t
只生成1,而当它不存在时,则生成NULL。如果它不存在,则使用导入表中的MemberNo。
子查询n
获取目标表中的最大MemberNo
。仅在导入表中的MemberNo已存在的情况下使用。然后,为了不需要循环,它使用ROW_NUMBER
将每个新行的最大MemberNo增加1,以避免重复。
Example on SQL Fiddle (仅限SELECT用于演示目的)
如果您仍然需要进行更新,可以使用类似的查询:
WITH Import AS
( SELECT NewMemberNo = n.NextMemberNo + ROW_NUMBER() OVER(ORDER BY i.MemberNo),
i.MemberNo
FROM ImportTable i
CROSS JOIN
( SELECT NextMemberNo = MAX(MemberNo)
FROM TargetTable
) n
WHERE EXISTS
( SELECT 1
FROM TargetTable t
WHERE t.MemberNo = i.MemberNo
)
)
UPDATE Import
SET MemberNo = NewMemberNo;
<强> UPDATE example on SQL Fiddle 强>