Je lisais un livre SQL, l'une des questions est:
Écrivez une requête sur la table Sales.Customers qui renvoie pour chaque client l'ID client et la région. Trier les lignes de la sortie par région, en ayant les marques NULL en dernier (après les valeurs non NULL) .Notez que le comportement de tri par défaut pour les marques NULL dans T-SQL est de trier en premier (avant les valeurs non NULL). Em >
Et la réponse est:
ORDER BY custid, region --because custid is the first column
Je peux taper pour avoir l'idée mais toujours confus, prenons l'enregistrement avec custid = 9 par exemple: puisque custid 9 a une région nulle, dans le cas où cstatement renvoie 1, la requête est donc comme:
ORDER BY 1, region
ce qui équivaut à:
SELECT custid, region FROM Sales.Customers ORDER BY CASE WHEN region IS NULL THEN 1 ELSE 0 END, region;
alors comment se fait-il que le custid 9 ne soit pas avant custid 10 (le deuxième enregistrement dans la sortie)? cette sortie ne doit-elle pas être triée par custid en premier, donc 9 est avant 10?
5 Réponses :
Vous pouvez essayer ci-dessous - dans votre cas, 0 sera comigné en premier puis 1, vous devez donc changer l'ordre de la valeur, ou vous pouvez faire un ordre de descente si vous ne voulez pas changer la valeur
SELECT custid, region FROM Sales.Customers ORDER BY CASE WHEN region IS NULL THEN 0 ELSE 1 END, region
désolé, n'obtiens pas votre réponse, si la région n'est pas nulle, alors triez d'abord par custid, ce qui est évidemment incorrect
Votre interprétation est incorrecte. Le 1
est un simple nombre, pas une référence de colonne.
La requête équivaut à:
ORDER BY 1 + 0
Il s'agit d'une distinction importante concernant les nombres dans le ORDER BY
. L'expression:
ORDER BY 1
fait référence à la première colonne. Cependant,
SELECT custid, region FROM (SELECT c.*, (CASE WHEN region IS NULL THEN 1 ELSE 0 END) as region_is_null FROM Sales.Customers c ) c ORDER BY region_is_null, region;
est simplement une expression numérique qui renvoie la constante 1
- et entraînera une erreur dans SQL Server (qui n'autorise pas constantes dans ORDER BY
).
donc la requête est qc comme
custid region case... 42 BC 0 10 BC 0 45 CA 0 9 NULL 1 8 NULL 1Non, c'est incorrect. L'expression
CASE WHEN region IS NULL THEN 1 ELSE 0 END
est évaluée par ligne; et le1
est une valeur au lieu de la position de la colonne. La position de la colonne dansORDER BY
ne peut être spécifiée que comme un littéral et non comme une expression. Donc ceci:custid region case... 10 BC 0 42 BC 0 45 CA 0 8 NULL 1 9 NULL 1Devient:
custid region case... 8 NULL 1 9 NULL 1 10 BC 0 42 BC 0 45 CA 0Et les résultats triés pourraient être:
custid region 8 NULL 9 NULL 10 BC 42 BC 45 CAOu:
ORDER BY 1, region
custid | region | new column ... 10 | BC | 0 ... 9 | NULL | 1 ...
L'idée est d'utiliser l'instruction CASE pour créer une colonne virtuelle de calcul pour marquer les valeurs nulles comme 0 et aucune valeur nulle comme 1, puis trier en conséquence.
si vous utilisez 0 dans l'ordre par clause, vous obtiendrez une erreur car vous n'avez pas de colonne à la position 0, même si vous réorganisez les colonnes sélectionnées, le résultat sera le même. donc la sortie de l'instruction case n'est pas une position de colonne, c'est une colonne calculée.
customer_id region marker not important if null 0