web-dev-qa-db-fra.com

SQL Server: Différence entre PARTITION BY et GROUP BY

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?

291
Mike Mooney

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.

353
Andomar

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. 

192
Arunprasanth K V

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

35
Will Marcouiller

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.

27
adolf garlic

PARTITION BY est analytique, alors que GROUP BY est agrégé. Pour utiliser PARTITION BY, vous devez le contenir avec une clause OVER .

23
OMG Ponies

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 .

20
yoel halb

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/

0
Alev Ryustemov

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.

0
user1785960