Pourquoi est-ce que lorsque nous avons une valeur NULL dans une colonne et que nous classons par valeur croissante, les NULL sont triés en premier?
select 1 as test
union all
select 2
union all
select NULL
union all
select 3
union all
select 4
order by test
résulte en
NULL
1
2
3
4
Je continue de penser que NULL signifiait "Indéterminant" ou possible "Inconnu". Si c'est vrai, ne trieraient-ils pas en dernier, car la valeur pourrait être supérieure à toutes les autres valeurs? (Ou est-ce une option de tri quelque part?)
Je suis sur SQL Server 2008R2, mais je soupçonne que cela est vrai sur tous les serveurs SQL et probablement sur tous les SGBDR.
sql-server
database-theory
sorting
Richard
la source
la source
desc
ordre pour afficher les choses les plus importantes ou les plus récentes, auquel cas je serais heureux que les choses nulles soient les dernières.Réponses:
NULL signifie inconnu. Aucune autre interprétation n'est valable.
Il n'y a pas pourrait être . Il n'y a aucune valeur potentielle . Inconnu est inconnu est inconnu.
Quant à savoir pourquoi il apparaît en premier, plutôt qu'en dernier, cela n'est pas pris en charge par les normes SQL publiées et est malheureusement laissé à la discrétion du fournisseur du SGBDR:
la source
Vous avez raison, cela
NULL
peut signifier «Indéterminant» ou «Uknownn» ou «Pas encore connu» ou «Ne pas appliquer». Mais il n'y a aucune raison de placer les Nulls en premier ou en dernier. Si nous ne connaissons pas les valeurs réelles, alors ils peuvent être petits ou grands.Je pense que la norme pour déterminer le comportement souhaité de Nulls pendant le tri est:
Malheureusement, SQL-Server n'a pas encore adopté cette syntaxe. Si je ne me trompe pas, PostgreSQL et Oracle l'ont.
Une solution:
Une autre solution qui doit être ajustée en fonction du type de données - mais qui ne fonctionnera pas bien, car elle ne peut pas utiliser d'index sur
(test)
:la source
Je ne sais pas pourquoi cela est fait de cette façon, mais par définition, NULLS ne peut pas être comparé à des non-NULLS, donc ils doivent aller au début ou à la fin (la réponse de Mark couvre cela plus en détail).
Pour obtenir le comportement que vous souhaitez - Pour autant que je sache, il n'y a pas d'option de tri pour mettre les valeurs nulles en dernier, vous devez donc les héberger en utilisant une colonne calculée pour les forcer en dernier. Cependant, dans SQL Server, vous ne pouvez pas trier par une colonne calculée (
CASE WHEN ...
) lorsque vos données contiennent un opérateur set (UNION ALL
). Donc:Fonctionne pour le tri des valeurs nulles en dernier. Si vous devez utiliser
UNION
(ouEXCEPT
ouINTERSECTS
) pour générer votre ensemble de données, sauvegardez vos données dans une table temporaire comme ci-dessus.la source
Si vous avez affaire à des chiffres, vous pouvez également utiliser
NULL
sont les valeurs les plus basses possibles, lesDESC
met donc à la fin. Pendant ce temps, les valeurs non nulles ont le signe inversé, ceDESC
qui correspond en faitASC
aux valeurs réelles. Cela devrait être plus rapide queCASE
et je suppose que l'optimiseur de requêtes peut également utiliser des index sur latest
colonne.la source
(- test)
.