Sql 以不重复对a和b的引用的方式对谓词进行排序。对于非确定性表达式a和b,或具有副作用的表达式(如日志记录),这将非常有用。您的第二个示例还模拟了(A.Col1,A.Col2,A.Col3)与(B.Col1,B.Col2,B.Col3),后者仅由Postgre

Sql 以不重复对a和b的引用的方式对谓词进行排序。对于非确定性表达式a和b,或具有副作用的表达式(如日志记录),这将非常有用。您的第二个示例还模拟了(A.Col1,A.Col2,A.Col3)与(B.Col1,B.Col2,B.Col3),后者仅由Postgre,sql,sql-server,tsql,sql-server-2008-r2,ansi-sql,Sql,Sql Server,Tsql,Sql Server 2008 R2,Ansi Sql,以不重复对a和b的引用的方式对谓词进行排序。对于非确定性表达式a和b,或具有副作用的表达式(如日志记录),这将非常有用。您的第二个示例还模拟了(A.Col1,A.Col2,A.Col3)与(B.Col1,B.Col2,B.Col3),后者仅由PostgreSQL本机支持(据我所知)。有时,这是一个非常有用的谓词。存在(…intersect…idea)。当a和b是长表达式时非常有用。我修改了一些查询,这些查询的谓词与这里的其他答案类似。我得出结论,使用INTERSECT可以获得更快的查询速度。谢谢


以不重复对
a
b
的引用的方式对谓词进行排序。对于非确定性表达式
a
b
,或具有副作用的表达式(如日志记录),这将非常有用。您的第二个示例还模拟了
(A.Col1,A.Col2,A.Col3)与(B.Col1,B.Col2,B.Col3)
,后者仅由PostgreSQL本机支持(据我所知)。有时,这是一个非常有用的谓词。
存在(…intersect…
idea)。当a和b是长表达式时非常有用。我修改了一些查询,这些查询的谓词与这里的其他答案类似。我得出结论,使用
INTERSECT
可以获得更快的查询速度。谢谢分享!((a b或a为空或b为空)而不是(a为空且b为空)):我们不能只使用ab或a为空或xor b为空为什么我们不能重写
a与b
的不同之处在于
a=b或a为空且b为空
?这样看起来更简洁。@Rudey,因为当只有一个操作数为null时,
a=b
的计算结果为null,这会导致整个表达式的计算结果为null。
是否与sql server 2019中实现的
不同?它没有在sql server 2017中实现。@不,sql server 2019仍然不支持与不同的
-它也没有任何方法可以简洁地执行空安全比较(除了在谓词中使用集合操作,这对于标量比较是不切实际的)。+1用于说明函数如何终止索引的使用。我就是这样来到这里的。
a IS DISTINCT FROM b <==>
(
    ((a) IS NULL AND (b) IS NOT NULL)
OR
    ((a) IS NOT NULL AND (b) IS NULL)
OR
    ((a) <> (b))
)

a IS NOT DISTINCT FROM b <==>
(
    ((a) IS NULL AND (b) IS NULL)
OR
    ((a) = (b))
)
a IS DISTINCT FROM b <==> COALESCE(a, placeholder) <> COALESCE(b, placeholder)
a IS NOT DISTINCT FROM b <==> COALESCE(a, placeholder) = COALESCE(b, placeholder)
WHERE COALESCE(@input, x) = COALESCE(column, x)
WHERE @input = column OR (@input IS NULL AND column IS NULL)
SELECT *
FROM TableA A
   INNER JOIN TableB B ON A.PK = B.PK
WHERE NOT EXISTS(
   SELECT A.Col1, A.Col2, A.Col3
   INTERSECT
   SELECT B.Col1, B.Col2, B.Col3);
CASE WHEN [a] IS     NULL AND [b] IS     NULL THEN FALSE
     WHEN [a] IS     NULL AND [b] IS NOT NULL THEN TRUE
     WHEN [a] IS NOT NULL AND [b] IS     NULL THEN TRUE
     WHEN [a] =               [b]             THEN FALSE
     ELSE                                          TRUE
END
a IS NOT DISTINCT FROM b
(a IS NOT NULL AND b IS NOT NULL AND a=b) OR (a IS NULL AND b is NULL)
a IS DISTINCT FROM b
NOT (a IS NOT DISTINCT FROM b)
a IS DISTINCT FROM b
<=>
EXISTS (SELECT a EXCEPT SELECT b)
-- NOT EXISTS (SELECT a INTERSECT SELECT b)
a IS NOT DISTINCT FROM  b
<=>
NOT EXISTS (SELECT a EXCEPT SELECT b)
-- EXISTS (SELECT a INTERSECT SELECT b)
SELECT 1 AS PK, 21 AS c, NULL  AS  b
INTO tab1;

SELECT 1 AS PK, 21 AS c, 2 AS b
INTO tab2;

SELECT *
FROM tab1 A
JOIN tab2 B ON A.PK = B.PK
WHERE EXISTS(SELECT A.c, A.B
              EXCEPT
              SELECT B.c, B.b);
-- a IS DISTINCT FROM b
CASE WHEN (a = b) OR (a IS NULL AND b IS NULL) THEN 1 ELSE 0 END = 0

-- a IS NOT DISTINCT FROM b
CASE WHEN (a = b) OR (a IS NULL AND b IS NULL) THEN 1 ELSE 0 END = 1