在SQL Server中,DISTINCT NULL将返回单个NULL。

17
在SQL Server中,NULL不等于NULL。(参见为什么在SQL Server中,NULL = NULL 的结果为假) 那么为什么以下代码返回单个NULL?
CREATE TABLE #TEMP1
    (ID INT)
INSERT INTO #TEMP1
SELECT NULL
UNION ALL
SELECT NULL
SELECT DISTINCT ID FROM #TEMP1
DROP TABLE #TEMP1

ID
------
NULL

我预期

ID
------
NULL
NULL

8
链接1: https://en.wikipedia.org/wiki/Null_(SQL)#When_two_nulls_are_equal:_grouping,_sorting,_and_some_set_operations当在 SQL 中比较两个空值时,其结果通常是未定义的。但是,在分组、排序和某些集合操作中,两个空值被视为相等。这意味着,如果您对包含空值的列进行分组、排序或执行集合操作(例如 UNION 或 EXCEPT),则它们将被视为相同的行。链接2: https://modern-sql.com/concept/null#equals-vs-distinct在 SQL 中,NULL 不等于任何其他值,甚至不等于另一个 NULL 值。在比较值时,可以使用 "IS NULL" 或 "IS NOT NULL" 操作符来检查是否为空。而在比较具有 NULL 值的行时,需要使用 IS DISTINCT FROM 或 "=" 操作符的扩展版本,以便正确地处理 NULL 值并避免错误的比较结果。 - Martin Smith
2个回答

35

文档中,对于DISTINCT比较处理NULL值的方法有明确阐述。摘录如下:

DISTINCT

指定结果集中只允许出现独特的行。 在使用DISTINCT关键字时,NULL值被视为相等。


在SQL标准中,UNION中的DISTINCT遵循您的引用。然而,在其他地方,具有NULL但相同的行是不同的。对于UNION DISTINCT,MS Server遵循标准,但在其他地方则不是。我提到这一点是为了那些使用不同DBMS的人们。 - philipxy

1
不仅在文档中有说明,而且这是一种不同类型的等式测试。未知是否等于未知?谁知道,也许是,也许不是。但这正是Distinct应该只返回1的原因。如果它返回了2个不同的值,那就意味着这些未知数是不同的。至少存在一个未知值,因此它应该在列表中,无论它是否与其他未知值不同都是未知的。

对于Intersect,空值也被视为相等。

Select 1
Where exists (select null intersect select null)

SQL中的NULL是临时性的,你无法根据它们在其他地方的行为或某种“未知”的概念来推断它们在哪里起作用。没有“应该”。SQL标准UNION DISTINCT不同于使用distinct的其他方法,在MS Server中,使用distinct的其他方法遵循标准。 - philipxy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接