IS [NOT] DISTINCT FROM (Transact-SQL)

适用于: SQL Server 2022 (16.x)

比较两个表达式的相等性,并保证一个 true 或 false 结果,即使一个或两个操作数均为 NULL。

IS [NOT] DISTINCT FROM 这一谓词用于 WHERE 子句和 HAVING 子句的搜索条件中,还用于 FROM子句的联接条件以及需要布尔值的其他构造中。

Transact-SQL 语法约定

语法

expression IS [NOT] DISTINCT FROM expression

参数

expression

任何有效的表达式

该表达式可以是列、常量、函数、变量、标量子查询,或者是通过运算符或子查询连接的列名、常量和函数的任意组合。

备注

将 NULL 值与任何其他值(包括另一个 NULL)进行比较将产生未知结果。 IS [NOT] DISTINCT FROM 将始终返回 true 或 false,因为在用作比较运算符时,它将 NULL 值视为已知值。

以下示例表使用值 AB 来说明 IS [NOT] DISTINCT FROM 的行为:

A B A = B A IS NOT DISTINCT FROM B
0 0 True True
0 1 False False
0 Null 未知 False
Null Null Unknown True

针对链接服务器执行包含 IS [NOT] DISTINCT FROM 的查询时,发送到链接服务器的查询文本将有所不同,具体取决于我们能否确定链接服务器有能力分析语法。

如果我们确定链接服务器可分析 IS [NOT] DISTINCT FROM,则将按原样解码语法。 如果无法确定链接服务器可否分析 IS [NOT] DISTINCT FROM,则将解码为以下表达式:

A IS DISTINCT FROM B 将解码为:((A <> B OR A IS NULL OR B IS NULL) AND NOT (A IS NULL AND B IS NULL))

A IS NOT DISTINCT FROM B 将解码为:(NOT (A <> B OR A IS NULL OR B IS NULL) OR (A IS NULL AND B IS NULL))

示例

A. 使用 IS DISTINCT FROM

以下示例返回 id 字段与整数值 17 不同的行。

USE tempdb;
GO
DROP TABLE IF EXISTS #SampleTempTable;
GO
CREATE TABLE #SampleTempTable (id INT, message nvarchar(50));
INSERT INTO #SampleTempTable VALUES (null, 'hello') ;
INSERT INTO #SampleTempTable VALUES (10, null);
INSERT INTO #SampleTempTable VALUES (17, 'abc');
INSERT INTO #SampleTempTable VALUES (17, 'yes');
INSERT INTO #SampleTempTable VALUES (null, null);
GO

SELECT * FROM #SampleTempTable WHERE id IS DISTINCT FROM 17;

结果排除了 id 与值 17 匹配的所有行。

id          message
----------- ---------
NULL        hello
10          NULL
NULL        NULL

B. 使用 IS NOT DISTINCT FROM

以下示例返回 id 字段与整数值 17 相同的行。

USE tempdb;
GO
DROP TABLE IF EXISTS #SampleTempTable;
GO
CREATE TABLE #SampleTempTable (id INT, message nvarchar(50));
INSERT INTO #SampleTempTable VALUES (null, 'hello') ;
INSERT INTO #SampleTempTable VALUES (10, null);
INSERT INTO #SampleTempTable VALUES (17, 'abc');
INSERT INTO #SampleTempTable VALUES (17, 'yes');
INSERT INTO #SampleTempTable VALUES (null, null);
GO

SELECT * FROM #SampleTempTable WHERE id IS NOT DISTINCT FROM 17;

结果仅返回 id 与值 17 匹配的行。

id          message
----------- --------
17          abc
17          yes

C. 针对 NULL 值使用 IS DISTINCT FROM

以下示例返回 id 字段与 NULL 不同的行。

USE tempdb;
GO
DROP TABLE IF EXISTS #SampleTempTable;
GO
CREATE TABLE #SampleTempTable (id INT, message nvarchar(50));
INSERT INTO #SampleTempTable VALUES (null, 'hello') ;
INSERT INTO #SampleTempTable VALUES (10, null);
INSERT INTO #SampleTempTable VALUES (17, 'abc');
INSERT INTO #SampleTempTable VALUES (17, 'yes');
INSERT INTO #SampleTempTable VALUES (null, null);
GO

SELECT * FROM #SampleTempTable WHERE id IS DISTINCT FROM NULL;

结果仅返回 id 不是 NULL 的行。

id          message
----------- --------
10          NULL
17          abc
17          yes

D. 针对 NULL 值使用 IS NOT DISTINCT FROM

以下示例返回 id 字段与 NULL 相同的行。

USE tempdb;
GO
DROP TABLE IF EXISTS #SampleTempTable;
GO
CREATE TABLE #SampleTempTable (id INT, message nvarchar(50));
INSERT INTO #SampleTempTable VALUES (null, 'hello') ;
INSERT INTO #SampleTempTable VALUES (10, null);
INSERT INTO #SampleTempTable VALUES (17, 'abc');
INSERT INTO #SampleTempTable VALUES (17, 'yes');
INSERT INTO #SampleTempTable VALUES (null, null);
GO

SELECT * FROM #SampleTempTable WHERE id IS NOT DISTINCT FROM NULL;

结果仅返回 id 是 NULL 的行。

id          message
----------- --------
NULL        hello
NULL        NULL

请参阅