J'utilise GROUP BY
pour tous les types de requêtes globales au fil des ans. Récemment, j'ai procédé au reverse engineering de code qui utilise PARTITION BY
pour effectuer des agrégations. En parcourant toute la documentation que je peux trouver sur PARTITION BY
, cela ressemble beaucoup à GROUP BY
, avec peut-être un peu de fonctionnalités supplémentaires? S'agit-il de deux versions de la même fonctionnalité générale, ou s'agit-il de quelque chose de totalement différent?
Ils sont utilisés dans des endroits différents. group by
modifie la requête entière, comme suit:
select customerId, count(*) as orderCount
from Orders
group by customerId
Mais partition by
ne fonctionne que sur une fonction de fenêtre , comme row_number
:
select row_number() over (partition by customerId order by orderId)
as OrderNumberForThisCustomer
from Orders
Un group by
réduit normalement le nombre de lignes renvoyées en les cumulant et en calculant des moyennes ou des sommes pour chaque ligne. partition by
n'affecte pas le nombre de lignes renvoyées, mais il modifie le calcul du résultat d'une fonction de fenêtre.
Nous pouvons prendre un exemple simple
nous avons une table nommée TableA
avec les valeurs suivantes.
id firstname lastname Mark
-------------------------------------------------------------------
1 arun prasanth 40
2 ann antony 45
3 sruthy abc 41
6 new abc 47
1 arun prasanth 45
1 arun prasanth 49
2 ann antony 49
Par groupe
La clause SQL GROUP BY peut être utilisée dans une instruction SELECT pour collecter données sur plusieurs enregistrements et regrouper les résultats en un ou plusieurs colonnes.
En termes plus simples, l'instruction GROUP BY est utilisée conjointement avec les fonctions d'agrégation pour regrouper le résultat par un ou plusieurs colonnes.
syntaxe:
SELECT expression1, expression2, ... expression_n,
aggregate_function (aggregate_expression)
FROM tables
WHERE conditions
GROUP BY expression1, expression2, ... expression_n;
Nous pouvons appliquer GroupBy dans notre tableau
select SUM(Mark)marksum,firstname from TableA
group by id,firstName
Résultats :
marksum firstname
----------------
94 ann
134 arun
47 new
41 sruthy
Dans notre table réelle, nous avons 7 lignes et lorsque nous appliquons groupe par identifiant, le serveur regroupe les résultats en fonction de l'identifiant
En mots simples
here group by réduit normalement le nombre de lignes renvoyées par roulement les monter et calculer la somme pour chaque ligne.
partition par
avant d'aller partitionner
voyons la clause OVER
Selon la définition MSDN
La clause OVER définit une fenêtre ou un ensemble de lignes spécifié par l'utilisateur dans un fichier ensemble de résultats de la requête. Une fonction window calcule ensuite une valeur pour chaque ligne dans la fenêtre. Vous pouvez utiliser la clause OVER avec des fonctions pour calculer valeurs agrégées telles que moyennes mobiles, agrégats cumulés, totaux en cours, ou un top N par groupe.
partition by ne réduira pas le nombre de lignes renvoyées
nous pouvons appliquer la partition par dans notre exemple de table
select SUM(Mark) OVER (PARTITION BY id) AS marksum, firstname from TableA
résultat :
marksum firstname
-------------------
134 arun
134 arun
134 arun
94 ann
94 ann
41 sruthy
47 new
regardez les résultats, il partitionnera les lignes et les résultats ne seront pas comme group par.
partition by
ne cumule pas les données. Cela vous permet de réinitialiser quelque chose par groupe. Par exemple, vous pouvez obtenir une colonne ordinale au sein d'un groupe en partitionnant le champ de regroupement et en utilisant rownum()
sur les lignes de ce groupe. Cela vous donne quelque chose qui se comporte un peu comme une colonne d’identité qui se réinitialise au début de chaque groupe.
PARTAGE PAR Divise le jeu de résultats en partitions. La fonction de fenêtre est appliquée à chaque partition séparément et le calcul redémarre pour chaque partition.
Trouvé à ce lien: Clause OVER
Il fournit des données enroulées sans rouler
i.e. Supposons que je veuille renvoyer la position relative de la région de vente
En utilisant PARTITION BY, je peux renvoyer le montant des ventes pour une région donnée et le montant MAX pour toutes les régions de vente de la même ligne.
Cela signifie que vous aurez des données répétitives, mais cela peut convenir au consommateur final en ce sens que les données ont été agrégées mais aucune donnée n'a été perdue - comme ce serait le cas avec GROUP BY.
PARTITION BY
est analytique, alors que GROUP BY
est agrégé. Pour utiliser PARTITION BY
, vous devez le contenir avec une clause OVER .
D'après ce que j'ai compris, Partition By est presque identique à Group By, mais avec les différences suivantes:
Ce groupe regroupe en fait le jeu de résultats renvoyant une ligne par groupe, ce qui a pour conséquence que SQL Server n'autorise dans la liste SELECT que des fonctions d'agrégation ou des colonnes faisant partie de la clause group by (dans ce cas, SQL Server peut garantir qu'il existe des droits uniques. résultats pour chaque groupe).
Considérons par exemple MySQL qui permet d'avoir dans la liste SELECT des colonnes qui ne sont pas définies dans la clause Group By, auquel cas une ligne est toujours renvoyée par groupe. Cependant, si la colonne n'a pas de résultats uniques, il n'y a aucune garantie. quelle sera la sortie!
Mais avec Partition By, bien que les résultats de la fonction soient identiques à ceux d’une fonction agrégée avec Group By, vous obtenez toujours le jeu de résultats normal, ce qui signifie qu’on obtient une ligne par ligne sous-jacente, et non une ligne par groupe, et à cause de cela, on peut avoir des colonnes qui ne sont pas uniques par groupe dans la liste SELECT.
Donc, en résumé, Group By serait le meilleur choix si une sortie d’une ligne par groupe était nécessaire, et Partition By était préférable lorsque l’ensemble des lignes était nécessaire, mais que la fonction d’agrégation était toujours basée sur un groupe.
Bien sûr, il peut aussi y avoir des problèmes de performances, voir http://social.msdn.Microsoft.com/Forums/ms-MY/transactsql/thread/0b20c2b5-1607-40bc-b7a7-0c60a2a55fba .
Il a vraiment différents scénarios d'utilisation. Lorsque vous utilisez GROUP BY, vous fusionnez certains des enregistrements des colonnes identiques et vous obtenez une agrégation du jeu de résultats.
Toutefois, lorsque vous utilisez PARTITION BY, votre jeu de résultats est identique, mais vous ne disposez que d'une agrégation sur les fonctions de fenêtre et vous ne fusionnez pas les enregistrements. Vous aurez toujours le même nombre d'enregistrements.
Voici un article utile sur le rallye expliquant la différence: http://alevryustemov.com/sql/sql-partition-by/
Petite observation. Mécanisme d'automatisation permettant de générer dynamiquement du code SQL à l'aide de la "partition par", il est beaucoup plus simple à mettre en œuvre par rapport au "groupe par". Dans le cas de 'group by', nous devons nous occuper du contenu de la colonne 'select'.
Désolé pour mon anglais.