J'utilise une application (MapServer - http://mapserver.org/ ) qui encapsule les instructions SQL, de sorte que l'instruction ORDER BY se trouve dans la requête interne. Par exemple
SELECT * FROM (
SELECT ID, GEOM, Name
FROM t
ORDER BY Name
) as tbl
L'application dispose de nombreux pilotes de base de données différents. J'utilise principalement le pilote MS SQL Server et SQL Server 2008. Cela génère une erreur si un ORDER BY est trouvé dans une sous-requête.
À partir de MS Docs (bien que ce soit pour SQL Server 2000, il semble toujours s'appliquer):
Lorsque vous utilisez une clause ORDER BY dans une vue, une fonction en ligne, une table dérivée ou une sous-requête, cela ne garantit pas la sortie ordonnée. Au lieu de cela, la clause ORDER BY est uniquement utilisée pour garantir que l'ensemble de résultats généré par l'opérateur Top a une composition cohérente. La clause ORDER BY garantit uniquement un jeu de résultats ordonné lorsqu'il est spécifié dans l'instruction SELECT la plus externe.
Cependant, le même type de requête lorsqu'il est exécuté dans Postgres (9) et Oracle renvoie des résultats - avec l'ordre défini dans la sous-requête. Dans Postgres, le plan de requête montre que les résultats sont triés et les notes de publication de Postgres incluent l'élément, ce qui implique que des ordres de sous-requête sont utilisés:
Évitez le tri lorsque la sous-requête ORDER BY correspond à la requête supérieure
http://en.wikipedia.org/wiki/Order_by déclare:
Bien que certains systèmes de base de données autorisent la spécification d'une clause ORDER BY dans les sous-sélections ou les définitions de vue, la présence n'a aucun effet.
Cependant, d'après ma propre vérification des plans de requête:
- SQL Server 2008 ne prend pas en charge ORDER BY dans une sous-requête
- Postgres 9 prend en charge ORDER BY dans une sous-requête
- Oracle 10g prend en charge ORDER BY dans une sous-requête
Donc, ma question existe-t-il des liens qui peuvent officiellement confirmer ou nier que Postgres et Oracle n'autorisent pas le tri dans une sous-requête?
la source
ORDER BY
dans la sous-requête comme redondant et ne feraient pas le tri inutile.Réponses:
Vous allez devoir faire en sorte que votre application ne mette pas l'
ORDER BY
intérieur de la sous-requête (peut-être qu'elle a une option pour ne pas utiliser une sous-requête inutile en premier lieu). Comme vous l'avez déjà découvert, cette syntaxe n'est pas prise en charge dans SQL Server sansTOP
. Et avecTOP
, à moins que vous ne vouliez laisser des lignes de côté, l'utilisationTOP 100 PERCENT
va de toute façon rendre le renduORDER BY
optimisé.Et dans Oracle et PostGres, ce n'est pas parce que la syntaxe est prise en charge qu'elle est respectée. Et le simple fait que vous l'observiez comme étant obéi dans certains scénarios ne signifie pas qu'il continuera à être obéi à mesure que de nouvelles versions sortent ou avec des modifications subtiles de vos données, statistiques, la requête elle-même ou l'environnement.
Je peux vous assurer que, sans aucun doute , si vous voulez une garantie sur la commande, vous devez mettre le
ORDER BY
sur la requête la plus externe. Cela devrait être une doctrine que vous gardez proche, quelle que soit la plateforme que vous utilisez.Vous demandez un lien indiquant officiellement que quelque chose n'est pas pris en charge. C'est comme regarder dans le manuel du propriétaire de votre voiture pour une déclaration officielle que votre voiture ne peut pas voler.
la source
J'admets que c'est louche mais si vous êtes pressé, essayez de renvoyer le nombre supérieur de lignes dans la sous-requête. Le retour des 100% supérieurs ne fonctionne pas, mais si vous voulez passer par la difficulté, vous pouvez interroger le nombre de lignes et le transmettre à TOP en tant que variable. J'ai testé cela sur une base de données définie au niveau de compatibilité 80, donc je pense que cela devrait fonctionner avec SQL 2000.
la source
Name
n'est pas unique. Il peut ne pas continuer à fonctionner en série si l'optimiseur choisit un index différent, avec un ordre de colonne de clé différent.