J'ai utilisé GROUP BY
pour tous les types de requêtes d'agrégat au fil des ans. Récemment, j'ai fait du reverse-engineering de code qui utilise PARTITION BY
pour effectuer des agrégations. En lisant toute la documentation que je peux trouver sur PARTITION BY
, cela ressemble beaucoup à GROUP BY
, peut-être avec un peu de fonctionnalité supplémentaire ajouté? Sont-ils deux versions de la même fonctionnalité générale, ou sont-ils quelque chose de complètement différent?SQL Server: Différence entre PARTITION BY et GROUP BY
Répondre
Ils sont utilisés dans différents endroits. group by
modifie toute la requête, comme:
select customerId, count(*) as orderCount
from Orders
group by customerId
Mais partition by
fonctionne seulement sur a window function, 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 roulant et le calcul des moyennes ou des sommes pour chaque rangée. partition by
n'affecte pas le nombre de lignes renvoyées, mais modifie la façon dont le résultat d'une fonction de fenêtre est calculé.
partition by
ne fait pas rouler les données. Cela vous permet de réinitialiser quelque chose par groupe. Par exemple, vous pouvez obtenir une colonne ordinale dans 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.
PARTITION BY
est analytique, tandis que GROUP BY
est agrégé. Afin d'utiliser PARTITION BY
, vous devez le contenir avec un OVER clause.
'PARTITION BY est analytique', cette simple déclaration m'a beaucoup éclairé. +1 –
PARTITION BY 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: OVER Clause
Il fournit des données roulées sans rouler
-à-dire que je veuille revenir la position relative de la région de vente
Utiliser PARTITION BY, je peut renvoyer le montant des ventes pour une région donnée et le montant MAX pour toutes les régions de vente dans la même rangée. Cela signifie que vous aurez des données répétées, mais cela peut convenir au consommateur final dans le sens où les données ont été agrégées mais aucune donnée n'a été perdue - comme ce serait le cas avec GROUP BY.
La meilleure réponse, la plus simple. – tmthyjames
À partir de ma partition de compréhension En est presque identique au groupe par, mais avec les différences suivantes:
Ce groupe par des groupes en fait le résultat renvoyant un ensemble d'une ligne par groupe, ce qui entraîne donc dans SQL Server ne permet en la liste SELECT regroupe les fonctions ou les colonnes qui font partie de la clause group by (dans ce cas, SQL Server peut garantir des résultats uniques 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 retournée par groupe, mais si la colonne n'a pas de résultats uniques, alors il n'y a aucune garantie quelle sera la sortie! Mais avec Partition By, bien que les résultats de la fonction soient identiques aux résultats d'une fonction d'agrégation avec Group By, vous obtenez toujours le jeu de résultats normal, ce qui signifie que l'on obtient une ligne par ligne sous-jacente, et pas une rangée 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 mieux quand il faut une sortie d'une ligne par groupe, et Partition By serait mieux quand on a besoin de toutes les lignes mais veut toujours la fonction d'agrégat basée sur un groupe.
Bien sûr, il peut également y avoir des problèmes de performances, voir http://social.msdn.microsoft.com/Forums/ms-MY/transactsql/thread/0b20c2b5-1607-40bc-b7a7-0c60a2a55fba.
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
Groupe par
GROUP SQL BY clause peut être utilisée dans une instruction SELECT pour recueillir des données sur plusieurs enregistrements et regrouper les résultats par un ou plusieurs colonnes.
En termes plus simples, l'instruction GROUP BY est utilisée conjointement avec les fonctions d'agrégation pour regrouper l'ensemble de résultats par une 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 vraie table, nous avons 7 lignes et quand nous appliquons le groupe par id , Le groupe de serveurs les résultats basés sur id
En mots simples
ici groupe en réduit normalement le nombre de lignes renvoyées en roulant les et le calcul Somme pour chaque ligne.
partition par
avant d'aller à la partition par
regardons clause OVER
Comme par définition MSDN
OVER clause définit une fenêtre ou un ensemble de lignes spécifié par l'utilisateur wi affiner un ensemble 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, des agrégats cumulatifs, des totaux cumulés ou un résultat N par groupe supérieur.
partition en ne réduira pas le nombre de lignes retournées
nous pouvons appliquer la partition par dans notre exemple tableau
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
regard sur le résultats, il va partitionner les lignes et résultats toutes les lignes pas comme le groupe par.
-- BELOW IS A SAMPLE WHICH OUTLINES THE SIMPLE DIFFERENCES
-- READ IT AND THEN EXECUTE IT
-- THERE ARE THREE ROWS OF EACH COLOR INSERTED INTO THE TABLE
-- CREATE A database called testDB
-- use testDB
USE [TestDB]
GO
-- create Paints table
CREATE TABLE [dbo].[Paints](
[Color] [varchar](50) NULL,
[glossLevel] [varchar](50) NULL
) ON [PRIMARY]
GO
-- Populate Table
insert into paints (color, glossLevel)
select 'red', 'eggshell'
union
select 'red', 'glossy'
union
select 'red', 'flat'
union
select 'blue', 'eggshell'
union
select 'blue', 'glossy'
union
select 'blue', 'flat'
union
select 'orange', 'glossy'
union
select 'orange', 'flat'
union
select 'orange', 'eggshell'
union
select 'green', 'eggshell'
union
select 'green', 'glossy'
union
select 'green', 'flat'
union
select 'black', 'eggshell'
union
select 'black', 'glossy'
union
select 'black', 'flat'
union
select 'purple', 'eggshell'
union
select 'purple', 'glossy'
union
select 'purple', 'flat'
union
select 'salmon', 'eggshell'
union
select 'salmon', 'glossy'
union
select 'salmon', 'flat'
/* COMPARE 'GROUP BY' color to 'OVER (PARTITION BY Color)' */
-- GROUP BY Color
-- row quantity defined by group by
-- aggregate (count(*)) defined by group by
select count(*) from paints
group by color
-- OVER (PARTITION BY... Color
-- row quantity defined by main query
-- aggregate defined by OVER-PARTITION BY
select color
, glossLevel
, count(*) OVER (Partition by color)
from paints
/* COMPARE 'GROUP BY' color, glossLevel to 'OVER (PARTITION BY Color, GlossLevel)' */
-- GROUP BY Color, GlossLevel
-- row quantity defined by GROUP BY
-- aggregate (count(*)) defined by GROUP BY
select count(*) from paints
group by color, glossLevel
-- Partition by Color, GlossLevel
-- row quantity defined by main query
-- aggregate (count(*)) defined by OVER-PARTITION BY
select color
, glossLevel
, count(*) OVER (Partition by color, glossLevel)
from paints
Supposons que nous avons 14 dossiers de name
colonne dans le tableau
dans group by
select name,count(*) as totalcount from person where name='Please fill out' group BY name;
il donnera le nombre en ligne unique soit 14
mais partition by
select row_number() over (partition by name) as total from person where name = 'Please fill out';
il sera 14 rangées d'augmentation en nombre
Petite observation. Mécanisme d'automatisation pour générer dynamiquement du SQL en utilisant la 'partition par' il est beaucoup plus simple à implémenter par rapport au 'groupe par'. Dans le cas de 'group by', nous devons prendre en charge le contenu de la colonne 'select'.
Désolé pour mon anglais.
bonne réponse, pourriez-vous s'il vous plaît écrire un échantillon d'un résultat retourné pour chacun d'eux? –
@AshkanMobayenKhiabani vous pouvez exécuter les deux requêtes contre Northwind, qui peut ou non être installé par défaut en fonction de la version de votre serveur sql. Sinon, vous pouvez le rechercher sur la page des téléchargements. –
@AshkanMobayenKhiabani La réponse d'Arunprasanth ci-dessous montre des résultats retournés qui peuvent vous faire gagner du temps plutôt que de passer à travers des cerceaux d'apprentissage et du temps pour apprendre Northwind – Praxiteles