【发布时间】:2018-09-10 14:10:57
【问题描述】:
如果这个查询:
SELECT CONCAT(SOURCE.OrderNo, '_', SOURCE.OrderLine),
SOURCE.ProdOrder,
SOURCE.Lvl1,
SOURCE.Lvl2,
SOURCE.Lvl3,
SOURCE.LastDate
FROM dbo.SourceTbl AS SOURCE
返回 11 条记录和这个查询:
SELECT CONCAT(TARGET.OrderNo, '_', TARGET.OrderLine),
TARGET.ProdOrder,
TARGET.Lvl1,
TARGET.Lvl2,
TARGET.Lvl3,
TARGET.LastDate
FROM dbo.TargetTbl AS TARGET
返回 17 条记录和两者之间的 INTERSECT:
SELECT CONCAT(SOURCE.OrderNo, '_', SOURCE.OrderLine),
SOURCE.ProdOrder,
SOURCE.Lvl1,
SOURCE.Lvl2,
SOURCE.Lvl3,
SOURCE.LastDate
FROM dbo.SourceTbl AS SOURCE
INTERSECT
SELECT CONCAT(TARGET.OrderNo, '_', TARGET.OrderLine),
TARGET.ProdOrder,
TARGET.Lvl1,
TARGET.Lvl2,
TARGET.Lvl3,
TARGET.LastDate
FROM dbo.TargetTbl AS TARGET
当我像这样进行 MERGE 时返回 9 条记录:
MERGE dbo.TargetTbl AS TARGET
USING (
SELECT OrderNo, OrderLine, CONCAT(OrderNo, '_', OrderLine) AS OrderNoLine, SomeModel, ProdOrder, Lvl1, Lvl2, Lvl3,
MAX(LastDate) AS LastDate
FROM dbo.SourceTbl
GROUP BY OrderNo, OrderLine, CONCAT(OrderNo, '_', OrderLine), SomeModel, ProdOrder, Lvl1, Lvl2, Lvl3
) AS SOURCE
ON CONCAT(TARGET.OrderNo, '_', TARGET.OrderLine) = OrderNoLine
AND TARGET.ProdOrder = SOURCE.ProdOrder
AND TARGET.Lvl1 = SOURCE.Lvl1
AND TARGET.Lvl2 = SOURCE.Lvl2
AND TARGET.Lvl3 = SOURCE.Lvl3
AND TARGET.LastDate = SOURCE.LastDate
WHEN MATCHED AND EXISTS (SELECT CONCAT(SOURCE.OrderNo, '_', SOURCE.OrderLine)
,SOURCE.ProdOrder
,SOURCE.Lvl1
,SOURCE.Lvl2
,SOURCE.Lvl3
,SOURCE.LastDate
INTERSECT
SELECT CONCAT(TARGET.OrderNo, '_', TARGET.OrderLine)
,TARGET.ProdOrder
,TARGET.Lvl1
,TARGET.Lvl2
,TARGET.Lvl3
,TARGET.LastDate
)
THEN UPDATE SET TARGET.IsBlocked = 1, TARGET.BlockDate = GETDATE()
WHEN NOT MATCHED BY TARGET
THEN INSERT (LastDate, UsrID, DepID, OrderNo, OrderLine, SomeModel, ProdOrder, Lvl1, Lvl2, Lvl3, IsBlocked, BlockDate)
VALUES (SOURCE.LastDate, 999, 999, SOURCE.OrderNo, SOURCE.OrderLine, SOURCE.SomeModel, SOURCE.ProdOrder, SOURCE.Lvl1, SOURCE.Lvl2, SOURCE.Lvl3, 1, GETDATE());
它应该根据this 和this 更新 TargetTbl 的 9 条 INTERSECT 记录,并将 SourceTbl 中的剩余 2 条记录(总共 11 条)插入到同一个表中。相反,它更新 4 条记录并插入 6 条记录(总共 10 条)。 SourceTbl 中有两条记录重复,这就是 10 而不是 11 的原因,这也是我使用 MAX & GROUP BY 的原因。
我认为这是查询的第一部分,即 USING 部分,即使 INTERSECT 部分完成了它的工作,它也无法正确处理 NULL。我尝试了我能做的一切,但没有成功。我相信这很容易做到,所以请帮助我。谢谢。
编辑:SourceTbl 数据使用SELECT OrderNo, OrderLine, CONCAT(OrderNo, '_', OrderLine) AS OrderNoLine, SomeModel, ProdOrder, Lvl1, Lvl2, Lvl3, LastDate AS LastDate FROM dbo.SourceTbl ORDER BY OrderNo, OrderLine, SomeModel, ProdOrder,省略不相关的列:
OrderNo OrderLine OrderNoLine SomeModel ProdOrder Lvl1 Lvl2 Lvl3 LastDate
123c08637 10 123c08637_10 4321525175_004321 A5C008837 Abcd Efgh Olol 04/03/2030
123c11214 10 123c11214_10 4321532622_000391 NULL NULL NULL NULL 07/07/2018
123c13039 10 123c13039_10 4321525175_002611 A5C014838 NULL NULL NULL 18/05/2018
123c16059 10 123c16059_10 4321541488_001111 A5C018611 NULL NULL NULL 18/05/2018
123c17482 10 123c17482_10 4321506480_001711 A5C019227 Asdf Ghjk Cvnm 12/12/2018
123c17482 10 123c17482_10 4321506480_001711 A5C047712 Asdf Ghjk Cvnm 12/12/2018
123c17482 20 123c17482_20 4321506480_001712 A5B072554 aaaa bbbb cccc 18/05/2018
123c17482 20 123c17482_20 4321506480_001712 A5B072554 aaaa bbbb cccc 18/05/2018
123c17482 20 123c17482_20 4321506480_001712 A5B072554 aaaa bbbb xxxx 18/05/2018
123c17482 20 123c17482_20 4321506480_001712 A5B200472 NULL NULL NULL 18/05/2018
123c32405 10 123c32405_10 8765525667_005301 NULL Qwer Uiop Tygh 12/12/2018
【问题讨论】:
-
如果您添加了一个包含示例数据的脚本,这将使事情更容易讨论和理解。但是我认为您对“处理空值”的想法是错误的。 NULL 不能与任何返回布尔值(真/假)的值进行比较。它返回 。尝试使用空值加入(这是匹配发生的方式)根本行不通。 (待续)
-
此外,考虑到聚合和交集,您的更新逻辑似乎很可疑。我建议您将其分解为更简单的步骤。首先使用标准更新语句单独尝试更新部分。
标签: sql-server tsql merge null intersect