Question

Si j'ai quelques déclarations UNION comme exemple artificiel:

SELECT * FROM xxx WHERE z = 1
UNION 
SELECT * FROM xxx WHERE z = 2
UNION
SELECT * FROM xxx WHERE z = 3

Quel est le comportement par défaut par ?

Les données de test que je vois ne renvoient essentiellement pas les données dans l'ordre spécifié ci-dessus. C'est à dire. les données sont classées, mais je voulais savoir quelles sont les règles de priorité en la matière.

Une autre chose est que dans ce cas, xxx est une vue. La vue joint trois tables différentes pour obtenir les résultats souhaités.

Était-ce utile?

La solution

Il n'y a pas d'ordre par défaut.

Sans une clause Order By , l'ordre renvoyé n'est pas défini. Cela signifie que SQL Server peut les ramener dans l'ordre de leur choix.

EDIT: Sur la base de ce que j'ai vu, sans Order By, l'ordre dans lequel les résultats sont renvoyés dépend du plan de requête. Donc, s'il y a un index utilisé, le résultat peut revenir dans cet ordre, mais là encore, il n'y a aucune garantie.

Autres conseils

En ce qui concerne l'ajout d'une clause ORDER BY:

Ceci est probablement élémentaire pour la plupart des gens ici, mais je pensais l’ajouter. Parfois, vous ne voulez pas que les résultats soient mélangés, vous voulez donc les résultats de la première requête, puis ceux de la seconde, etc. Pour ce faire, je viens d’ajouter une première colonne fictive et de procéder par ordre. En raison de problèmes liés à l’oubli d’une colonne dans les unions, j’utilise généralement des ordinaux dans la clause order by, et non des noms de colonne.

Par exemple:

SELECT 1, * FROM xxx WHERE z = 'abc'
UNION ALL
SELECT 2, * FROM xxx WHERE z = 'def'
UNION ALL
SELECT 3, * FROM xxx WHERE z = 'ghi'
ORDER BY 1

La colonne ordinale factice est également utile lorsque je vais exécuter deux requêtes et que je ne sais qu’une seule renverra des résultats. Ensuite, je peux simplement vérifier l'ordinal des résultats renvoyés. Cela évite d'avoir à faire plusieurs appels à la base de données et à vérifier le plus souvent les résultats.

Je viens de trouver la réponse réelle.

Parce que UNION supprime les doublons, il effectue un TRI DISTINCT. Ceci est fait avant que toutes les instructions UNION soient concaténées (consultez le plan d’exécution).

Pour arrêter un tri, faites UNION ALL et cela ne supprimera pas les doublons.

Si l'ordre dans lequel les enregistrements sont renvoyés vous importe, vous DEVEZ utiliser un ordre avant.

Si vous le laissez pas, il peut paraître organisé (en fonction des index choisis par le plan de requête), mais les résultats que vous voyez aujourd'hui peuvent ne PAS être ceux que vous attendez, et même change lorsque la même requête est exécutée demain.

Édition: quelques bons exemples spécifiques: (tous les exemples sont des serveurs MS SQL)

  • Le blog de Dave Pinal décrit comment deux requêtes très similaires peuvent afficher un ordre apparent différent, car différents index sont utilisés:

    SELECT ContactID FROM Person.Contact
    SELECT *         FROM Person.Contact
    
  • Conor Cunningham montre comment l’ordre apparent peut changer lorsque la table grossit (si l’optimiseur de requêtes décide d’utiliser un plan d’exécution parallèle).

  • Hugo Kornelis prouve que l'ordre apparent est pas toujours basé sur la clé primaire. Voici son article de suivi avec une explication <. / p>

Une UNION peut être trompeuse en ce qui concerne l'ordre des résultats car une base de données utilise parfois une méthode de tri pour fournir le DISTINCT qui est implicite dans UNION, ce qui donne l'impression que les lignes ont été délibérément ordonnées - cela ne s'applique pas. à UNION ALL pour laquelle il n’existe pas de distinction implicite, bien sûr.

Cependant, il existe des algorithmes pour le distinct implicite, tels que la méthode de hachage d'Oracle dans 10g +, pour laquelle aucun ordre ne sera appliqué.

Comme le dit DJ, utilisez toujours un ORDER BY

Il est très courant de rencontrer du code mal écrit qui suppose que les données de la table sont renvoyées dans l’ordre d’insertion, et le codeur l’utilise sans le vouloir, et il n’a jamais conscience que cela pose un problème, comme sur de nombreuses bases de données courantes (MSSQL). , Oracle, MySQL). C’est bien sûr une erreur complète et il convient de corriger toujours quand cela se produit, et toujours, sans exception, utiliser vous-même une clause Order By.

D'après mon expérience pratique, vous pouvez modifier un ordre en utilisant "UNION". contre "UNION ALL" ... c'est à dire si votre requête ressemble à

Select Count(*) from Table A
UNION 
Select Count(*) from Table B

result is
10
26

vous pouvez inverser la commande en remplaçant "UNION". avec "UNION ALL" ... alors le résultat sera

26
10
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top