I comprendreque vousne peut pas avoirORDER BY
dans une vue. (Au moins dans SQL Server 2012 avec lequel je travaille)
Je comprends également que la manière "correcte" de trier une vue consiste à mettre un ORDER BY
autour de l'instruction SELECT
interrogeant la vue.
Mais étant relativement nouveau dans le SQL pratique et les utilisations des vues, je voudrais comprendre pourquoi cela se fait par conception. Si j'ai suivi correctement l'historique, cela était possible une fois et a été explicitement supprimé de SQL Server 2008 et ainsi de suite (ne me citez pas sur la version exacte).
Cependant, la meilleure raison pour laquelle je peux trouver pourquoi Microsoft a supprimé cette fonctionnalité est parce que "une vue est une collection de données non triée".
Je suppose qu'il existe une bonne raison logique pour laquelle une vue ne doit pas être triée. Pourquoi une vue ne peut-elle pas simplement être une collection de données aplatie? Pourquoi spécifiquement un - trié? Il ne semble pas si difficile de trouver des situations où (au moins pour moi/à mon humble avis) il semble parfaitement intuitif d'avoir une vue triée.
(Vues indexées de côté, bien sûr.)
Une vue n'est pas matérialisée - les données ne sont pas stockées, alors comment les trier? Une vue est un peu comme une procédure stockée qui contient juste un SELECT
sans paramètres ... elle ne contient pas de données, elle contient juste la définition de la requête. Étant donné que différentes références à la vue peuvent nécessiter le tri de données de différentes manières, la façon de procéder - tout comme la sélection dans une table, qui est également une collection de lignes non triée, par définition - consiste à inclure l'ordre par dans la requête externe .
Aussi pour donner un petit aperçu de l'histoire. Vous pourriez jamais mettre ORDER BY
dans une vue, sans inclure également TOP
. Et dans ce cas, le ORDER BY
dictait quelles lignes étaient incluses par TOP
, pas comment elles seraient présentées. Il se trouve que dans SQL Server 2000, si TOP
était 100 PERCENT
ou {some number >= number of rows in the table}
, l'optimiseur était assez simpliste et il a fini par produire un plan avec un tri qui correspondait à TOP/ORDER BY
. Mais ce comportement était jamais garanti ou documenté - il était juste basé sur l'observation, ce qui est une mauvaise habitude . Lorsque SQL Server 2005 est sorti, ce comportement a commencé à "casser" en raison de changements dans l'optimiseur qui ont conduit à l'utilisation de différents plans et opérateurs - entre autres, le TOP / ORDER BY
serait complètement ignoré s'il était TOP 100 PERCENT
. Certains clients se sont plaints de cela si fort que Microsoft a émis un indicateur de trace pour rétablir l'ancien comportement. Je ne vais pas vous dire ce qu'est l'indicateur parce que je ne veux pas que vous l'utilisiez et je veux m'assurer que l'intention est correcte - si vous voulez un ordre de tri prévisible, utilisez ORDER BY
sur la requête externe.
Pour résumer et tout autant pour clarifier un point que vous avez soulevé: Microsoft n'a rien supprimez rien. Ils ont amélioré le produit et, comme effet secondaire, ce comportement non documenté et non garanti est devenu moins fiable. Dans l'ensemble, je pense que le produit est meilleur pour cela.
Si une vue était autorisée à être triée, alors quel devrait être l'ordre du résultat ici?
CREATE VIEW dbo.V1
AS
SELECT number
FROM SomeTable
ORDER BY number ASC
GO
CREATE VIEW dbo.V2
AS
SELECT number
FROM SomeTable
ORDER BY number DESC
GO
SELECT *
FROM dbo.V1
JOIN dbo.V2
ON V1.number = V2.number
une possibilité consiste à éviter les tris contradictoires - si la vue est triée par un ordre et que la sélection sur cette vue est triée par un autre ordre (sans être conscient du tri de la vue), les performances peuvent être affectées. Il est donc plus sûr de laisser l'exigence de tri à l'utilisateur.
une autre raison, le tri entraîne un coût de performance, alors pourquoi pénaliser tous les utilisateurs de la vue, alors que seuls certains utilisateurs ont besoin du tri.
ANSI SQL autorise uniquement le ORDER BY
sur la requête la plus externe pour diverses raisons, l'une étant ce qui se produit lorsqu'une sous-sélection/vue/CTE est jointe à une autre table et que la requête externe a un ORDER BY
lui-même.
Le serveur SQL ne l'a jamais pris en charge dans une vue (sauf si vous l'avez trompé en utilisant un TOP 100 PERCENT
qui à mon avis déclenche principalement un bug).
Même si vous avez déclenché le bogue, les résultats n'ont jamais été fiables et le tri ne s'est pas toujours déroulé comme prévu.
Voir cet article de blog par l'équipe de l'Optimiseur de requête pour une explication technique complète ORDRE DE 100% PAR Considéré comme nuisible.
L'implémentation de plan par défaut pour ce code arrive à trier les lignes dans le cadre de l'exécution de l'opération TOP. Souvent, cela signifiait que les résultats étaient retournés dans l'ordre trié, ce qui a amené les clients à croire qu'il y avait une garantie que les lignes étaient triées. Ce n'est en fait pas le cas. Si vous souhaitez que les lignes soient renvoyées à l'utilisateur dans l'ordre trié, vous devez utiliser un ORDER BY sur le bloc de requête le plus à l'extérieur (par ANSI) pour garantir l'ordre de présentation de sortie.
Les vues se comportent comme des tables dont le contenu est déterminé par les résultats d'une requête.
Les tables n'ont pas d'ordre; ce ne sont que des sacs de rangées.
Par conséquent, les vues n'ont pas d'ordre non plus. Vous pouvez cependant les trier en sélectionnant des lignes dans une ORDRE particulière.