为什么UNION只返回一个null?

时间:2017-07-28 14:45:57

标签: sql-server tsql null

我理解null代表缺失/未知值,因此null不等于另一个null,因为无法比较两个未知事物。例如

if null = null
    select 'nulls are equal'
else
    select 'nulls are not equal'

结果'nulls are not equal'我在这里使用了=代替is nullis not null来强调无法比较两个空值的事实。

UNIONUNION应该消除重复值。我期望下面的代码返回两行null,因为两个null值不相等,但我在结果集中只得到一个空。

(select null as Col1)
union 
(select null as Col1)

为什么SQL对'null作为未知值'的解释会在上述两个语句中发生变化?

3 个答案:

答案 0 :(得分:4)

NULL无法比较,但SQL通常具有“IS DISTINCT FROM”的概念 SQL Server有一个Connect项目

  • 1来自NULL = true
  • 的DISTINCT
  • 1 = null是假的

为了完整性,NULL来自NULL = false

的DISTINCT

我猜DISTINCT和UNION使用IS DISTINCT FROM(如上面提到的Pரதீப்)

现在,SQL Server 确实在INTERSECT中有IS DISTINCT FROM并且除外

DECLARE @t1 TABLE (t1col INT);
INSERT @t1 VALUES (1), (NULL), (2), (3), (3), (5), (5);

DECLARE @t2 TABLE (t2col INT);
INSERT @t2 VALUES (1), (NULL), (3), (4);

SELECT DISTINCT 't1 EXISTS t2', * 
FROM @t1 t1 WHERE EXISTS (SELECT * FROM @t2 t2 WHERE t1.t1col = t2.t2col);

t1 EXISTS t2    1
t1 EXISTS t2    3
t1 EXISTS t2    3

SELECT DISTINCT 't1 INTERSECT t2', *
FROM @t1 INTERSECT SELECT 't1 INTERSECT t2', * FROM @t2;

t1 INTERSECT t2 NULL
t1 INTERSECT t2 1
t1 INTERSECT t2 3

INTERSECT和EXCEPT也会删除重复项,因为它们会进行半连接 EXISTS是反加入BTW

完整性

SELECT 't1 EXISTS t2', * 
FROM @t1 t1 WHERE NOT EXISTS (SELECT * FROM @t2 t2 WHERE t1.t1col = t2.t2col);

t1 EXISTS t2    NULL
t1 EXISTS t2    2
t1 EXISTS t2    5
t1 EXISTS t2    5

SELECT 't1 EXCEPT t2', * 
FROM @t1 EXCEPT SELECT 't1 EXCEPT t2', * FROM @t2;

t1 EXCEPT t2    2
t1 EXCEPT t2    5

从我的回答Why does EXCEPT exist in T-SQL?中添加了NULLs

的示例

答案 1 :(得分:2)

UNION基本上是SELECT DISTINCT,因此它会消除重复的NULL值,但它与Equal操作不同。

使用UNION ALL将为您提供所有记录,包括重复NULL。

至于你提问的第一部分。 NULL实际上等于NULL,但不是“=”。这会给你你期望的结果:

if null IS null
select 'nulls are equal'
else
select 'nulls are not equal'
处理空值时,

This也很有帮助。

答案 2 :(得分:0)

尝试使用UNION ALL保留两个集合中的所有内容,而不删除重复项。