Pourquoi UNION renvoie-t-il seulement une valeur nulle?

Je comprends que null représente une valeur manquante / inconnue, donc une valeur null n'est pas égale à une autre valeur null parce que deux choses inconnues ne peuvent pas être comparées. Par exemple

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

aboutit à 'nulls are not equal' J'ai utilisé an = place de is null ou is not null ici pour souligner le fait que deux nulls ne peuvent pas être comparés.

En arrivant à UNION , UNION est censé éliminer les duplicates. Je m'attendais à ce que le code ci-dessous returnne deux lignes chacune avec null puisque deux valeurs null ne sont pas égales, mais je reçois seulement une nulle dans le jeu de résultats.

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

Pourquoi l'interprétation de SQL de 'null comme valeur inconnue' change-t-elle dans deux déclarations?

NULL n'est pas comparable, mais SQL a généralement le concept de "IS DISTINCT FROM"
SQL Server a un élément Connect pour cela

  • 1 EST DISTINCT DE NULL = true
  • 1 = null est faux

Pour être complet, la NULL EST DISTINCT FROM NULL = false

Je suppose que l'utilisation DISTINCT et UNION IS DISTINCT FROM (comme P ரதீப் mentionné ci-dessus)

Maintenant, SQL Server a IS DISTINCT FROM dans INTERSECT et SAUF

 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 et EXCEPT suppriment également les duplicates car ils effectuent une semi-jointure
EXISTS est un anti-joint BTW

Pour l'exhaustivité

 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 

Exemple tiré de ma réponse Pourquoi EXCEPT existe-t-il dans T-SQL? avec des valeurs NULL ajoutées

UNION est essentiellement SELECT DISTINCT , ce qui éliminerait les valeurs NULL en double, mais ce n'est pas la même chose que l'opération Equal.

L'utilisation de UNION ALL vous donnerait tous les loggings, y compris la duplication des valeurs NULL.

Quant à la première partie de votre question. NULL est vraiment NULL, mais pas avec "=". Cela vous donnerait le résultat que vous attendez:

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

Ceci est également utile lorsque vous traitez des valeurs nulles.

Essayez UNION ALL pour conserver tout dans les deux sets sans supprimer les duplicates.