在合并语句中将 Null 与 Null 进行比较

Posted

技术标签:

【中文标题】在合并语句中将 Null 与 Null 进行比较【英文标题】:Comparing Null to Null in merge statement 【发布时间】:2013-01-10 16:30:20 【问题描述】:

在处理数十亿条记录以比较合并语句中的 NULL 时,哪种语句是完美或更好的。我尝试过使用 SET ANSI_NULLS OFF 但这在合并语句中不起作用。这是我的两种方式

ISNULL(SRCColumn,-11111) = ISNULL(DSTColumn, -11111)

或者

SRCColumn = DSTColumn OR (SRCColumn  IS NULL AND DSTColumn  IS NULL)

如果有更好的处理方法,请告诉我。因为我有大约 15 列要比较。

【问题讨论】:

这里的这个链接应该是ISO的做法,但它不被支持:请投票给这个connect.microsoft.com/SQLServer/feedback/details/286422/… 【参考方案1】:

SRCColumn = DSTColumn OR (SRCColumn IS NULL AND DSTColumn IS NULL)

我建议您使用此版本,因为它最准确地表达了您希望 SQL Server 执行的操作。

两个语句在逻辑上是等价的(除非 -11111 是该列的合法值),但是这个语句更容易识别,并且两个语句的运行时性能可能只有微不足道的差异。

【讨论】:

我用了同样的说法。不过,感谢您发布答案。我相信这对其他人也有帮助。【参考方案2】:

如果您更关心简洁而不是性能,CHECKSUM() 也是一种选择。它将匹配 NULL -> NULL:

MERGE A
USING B
ON A.Key = B.Key
WHEN MATCHED AND CHECKSUM(A.Col1, A.Col2, ... ) <> CHECKSUM(B.Col1, B.Col2, ... )
THEN UPDATE SET Col1 = B.Col1, Col1 = B.Col2, ...

【讨论】:

【参考方案3】:

如何在匹配中使用 NOT 比较:

MERGE [TGT]
USING [SRC]
ON [SRC].Key = [TGT]. Key
…

WHEN MATCHED AND
(
NOT ([TGT].[dw_patient_key] = [SRC].[dw_patient_key] OR ([TGT].[dw_patient_key] IS NULL AND [SRC].[dw_patient_key] IS NULL))
OR NOT ([TGT].[dw_patient_key] = [SRC].[dw_patient_key] OR ([TGT].[dw_patient_key] IS NULL AND [SRC].[dw_patient_key] IS NULL))
...
)
THEN UPDATE
...

【讨论】:

以上是关于在合并语句中将 Null 与 Null 进行比较的主要内容,如果未能解决你的问题,请参考以下文章

SQL 语句易错点讲解

在SQL Server中将多行相同id的行合并为一行[关闭]

Oracle:有没有一种简单的方法可以在合并/更新语句中说“如果 null 保持当前值”?

C++ 避免将 NULL 与 0 进行比较

在 Spark 中合并多行

Valgrind 将指针与 NULL 进行比较