5
votes

Quel est l'ordre d'exécution de la clause PARTITION BY par rapport aux autres clauses SQL?

Je ne trouve aucune source mentionnant l'ordre d'exécution des fonctions de la fenêtre Partition By dans SQL.

entrez la description de l'image ici

Est-ce dans dans le même ordre que Group By ?

Par exemple, un tableau comme: entrez la description de l'image ici

 entrez la description de l'image ici

Select top 1 *, row_number() over (Partition by Name order by Date) 
from NPtable 
Where Date > '2018-01-02 00:00:00'

Je comprends si Là où est exécuté en premier, il ne regardera que Name = 'Peter' , puis exécutera la fonction de fenêtre qui agrège simplement cette personne particulière au lieu de l'agrégation de table entière, ce qui est beaucoup plus efficace.

Mais lorsque la requête est:

Select *, row_number() over (Partition by Name) 
from NPtable 
Where Name = 'Peter'

La fonction de fenêtre n'a-t-elle pas besoin d'être d'abord exécutée sur toute la table puis applique la Date> condition sinon le résultat est faux?


2 commentaires

Quels sont les résultats? Et à quoi vous attendriez-vous?


Comment la fonction Window s'intègre-t-elle dans l'ordre d'exécution?


3 Réponses :


9
votes

Les fonctions de fenêtre sont exécutées / calculées au même stade que SELECT , étape 5 de votre tableau. En d'autres termes, les fonctions de fenêtre sont appliquées à toutes les lignes qui sont "visibles" à l'étape SELECT .

Dans votre deuxième exemple

Select top 1 *, 
row_number() over (Partition by Name order by Date) 
from NPtable 
Where Date > '2018-01-02 00:00:00'

WHERE est logiquement appliqué avant Partition by Name de la fonction row_number () .

Notez qu'il s'agit d'un ordre logique du traitement de la requête, pas nécessairement la manière dont le moteur traite physiquement les données.

Si l'optimiseur de requêtes décide qu'il est moins cher de scanner toute la table et de supprimer ultérieurement les dates selon le WHERE filtre, il peut le faire. Mais, tout type de ces transformations doit être effectué de telle manière que le résultat final soit cohérent avec l'ordre des étapes logiques décrites dans le tableau que vous avez montré.


2 commentaires

Je vous remercie. Cela dépendra donc de l'optimiseur d'exécuter la condition where en premier ou non dans la mesure où le résultat final est cohérent?


@NewPy, oui, la table que vous avez affichée avec l'ordre des étapes de traitement des requêtes est pour l'ordre logique . Il définit le résultat final de la requête. Il appartient au moteur / optimiseur de choisir un plan d'exécution physique qui produirait le résultat recherché. L'Optimiseur prend en compte de nombreux éléments et, dans certains cas, il peut choisir, par exemple, d'analyser la table entière au lieu de rechercher l'index. Il appliquera le filtre par la suite, mais le filtrage peut se produire plus tard que vous "prévu". Dans tous les cas, le résultat final de la requête sera correct et correspondra à l'ordre logique.



2
votes

row_number () (et d'autres fonctions de fenêtre) sont autorisées dans deux clauses:

  • SELECT
  • ORDER BY

La fonction est analysée avec le reste de la clause. Après tout, c'est une fonction présente dans la clause. Dans les deux cas, la clause WHERE serait - logiquement - appliquée en premier, donc les résultats seraient après filtrage.

Notez qu'il s'agit d'une analyse logique de la requête. L'exécution réelle peut avoir peu à voir avec la structure de la requête.


0 commentaires

2
votes

Il fait partie de la phase SELECT de l'exécution de la requête. Il existe différents types de clauses SELECT, basés sur la requête.

  • CHOISIR POUR
  • SÉLECTIONNER LE GROUPE PAR
  • SÉLECTIONNEZ LA COMMANDE PAR
  • SÉLECTIONNER PLUS
  • SÉLECTIONNER DANS
  • SÉLECTIONNER HAVING

PARTITION BY est fourni dans la clause SELECT OVER . Ici, une fenêtre du jeu de résultats est générée à partir du jeu de résultats généré aux étapes précédentes: FROM, WHERE, GROUP BY etc.

La clause OVER définit une fenêtre ou un ensemble de lignes spécifié par l'utilisateur dans un jeu de résultats de requête. Une fonction de fenêtre calcule ensuite une valeur pour chaque ligne dans la fenêtre. Vous pouvez utiliser la clause OVER avec des fonctions pour calculer des valeurs agrégées telles que des moyennes mobiles, cumulatives les agrégats, les totaux cumulés ou les N premiers résultats par groupe.

OVER ([PARTITION BY value_expression] [order_by_clause])

Arguments

PARTITION BY Divise l'ensemble de résultats de la requête en partitions. La fenêtre la fonction est appliquée à chaque partition séparément et le calcul redémarre pour chaque partition.

value_expression Spécifie la colonne par laquelle l'ensemble de lignes est partitionné. value_expression ne peut faire référence qu'aux colonnes mises à disposition par la clause FROM. value_expression ne peut pas faire référence à des expressions ou alias dans la liste de sélection. value_expression peut être une colonne expression, sous-requête scalaire, fonction scalaire ou définie par l'utilisateur variable.

<₹ Définit l'ordre logique des lignes dans chaque partition du jeu de résultats. Autrement dit, il spécifie l'ordre logique dans lequel le calcul de la fonction de la fenêtre est effectué.

order_by_expression Spécifie une colonne ou une expression sur laquelle trier. order_by_expression ne peut faire référence qu'aux colonnes mises à disposition par le Clause FROM. Un entier ne peut pas être spécifié pour représenter un nom de colonne ou alias.

Vous pouvez en savoir plus à ce sujet SELECT-OVER


0 commentaires