Question

Je me sers GROUP BY pour tous les types de requêtes agrégées au fil des ans. Récemment, j'ai reverse-engineering du code qui utilise PARTITION BY pour effectuer agrégations. En lisant à travers toute la documentation que je peux trouver à propos PARTITION BY, il ressemble beaucoup à GROUP BY, peut-être avec un peu de fonctionnalités supplémentaires ajoutée? Sont-ils deux versions de la même fonctionnalité générale, ou sont-ils tout à fait quelque chose de différent?

Était-ce utile?

La solution

Ils sont utilisés dans des endroits différents. group by modifie toute la requête, comme:

select customerId, count(*) as orderCount
from Orders
group by customerId

Mais partition by fonctionne sur une fonction de fenêtre , comme row_number:

select row_number() over (partition by customerId order by orderId)
    as OrderNumberForThisCustomer
from Orders

A group by réduit normalement le nombre de lignes renvoyées par les enroulant et en calculant des moyennes ou des sommes pour chaque ligne. partition by ne modifie pas le nombre de lignes retournées, mais il change la façon dont on calcule le résultat d'une fonction de fenêtre.

Autres conseils

Nous pouvons prendre un exemple simple.

Considérons 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

GROUP BY

  

Le groupe SQL BY clause peut être utilisée dans une instruction SELECT pour recueillir   données sur plusieurs disques et regrouper les résultats par un ou plusieurs   colonnes.

     

En termes plus simples GROUP BY est utilisé conjointement avec   les fonctions d'agrégation pour regrouper le résultat-ensemble 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 GROUP BY 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 lorsque nous appliquons GROUP BY id, le groupe de serveurs les résultats basés sur id:

En mots simples:

  

ici GROUP BY réduit normalement le nombre de lignes renvoyées en roulant   les et calcul Sum() pour chaque ligne.

PARTITION BY

Avant d'aller PARTITION BY, nous examinons la clause OVER:

Selon la définition MSDN:

  

OVER clause définit un ensemble de lignes ou de fenêtre spécifié par l'utilisateur dans un   résultat de la requête. Une fonction de fenêtre calcule alors une valeur pour chaque rangée   dans la fenêtre. Vous pouvez utiliser la clause OVER avec des fonctions pour calculer   valeurs agrégées telles que les moyennes mobiles, des agrégats cumulatifs,   tous les résultats en cours d'exécution, ou une partie supérieure de N par les résultats du groupe.

PARTITION BY ne réduira pas le nombre de lignes retournées.

Nous pouvons appliquer PARTITION BY dans notre tableau exemple:

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 partitionner les lignes et retourne tous lignes, à la différence GROUP BY

.

partition by ne roule pas réellement les données. Il vous permet de réinitialiser quelque chose sur une base par groupe. Par exemple, vous pouvez obtenir une colonne ordinale au sein d'un groupe en partageant sur le champ de regroupement et à l'aide rownum() sur les lignes de ce groupe. Cela vous donne quelque chose qui se comporte un peu comme une colonne d'identité qui remet à zéro au début de chaque groupe.

  

PAR PARTITION   Divise le jeu de résultats en partitions. La fonction de fenêtre est appliquée à chaque partition séparément et redémarrage de calcul pour chaque partition.

Trouvé à ce lien: SUR l'article

Il fournit des données roulées sans rouler

i.e.. Supposons que je veux retourner la position relative de la région de vente

Utilisation PARTITION BY, je peux retourner le montant des ventes pour une région donnée et le montant MAX dans toutes les régions de vente dans la même ligne.

Cela ne signifie que vous aurez à répéter des données, mais il 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 globale. Pour utiliser PARTITION BY, vous devez contenir avec un clause OVER .

de ma compréhension partition En est presque identique au groupe par, mais avec les différences suivantes:

Ce groupe par des groupes en fait le jeu de résultats de retour d'une ligne par groupe, ce qui en résulte donc que SQL Server permettant dans les fonctions d'agrégation de la liste SELECT ou des colonnes qui font partie du groupe par la clause (dans ce cas, SQL Server peut garantir que il y a des résultats uniques pour chaque groupe).

Considérons par exemple MySQL qui permet d'avoir dans les colonnes de la liste SELECT qui ne sont pas définis dans le groupe par la clause, auquel cas une ligne est toujours renvoyée par groupe, si la colonne n'a pas des résultats uniques alors il ne garantit ce sera la sortie!

Mais avec la partition par, bien que les résultats de la fonction sont identiques aux résultats d'une fonction d'agrégation avec Grouper par, encore vous obtenez le jeu normal des résultats, ce qui signifie que l'on est d'obtenir une ligne par ligne sous-jacente, et non une ligne par groupe, et à cause de celui-ci peut avoir des colonnes qui ne sont pas uniques par groupe dans la liste SELECT.

En résumé, groupe serait par mieux quand a besoin d'une sortie d'une ligne par groupe et par la partition serait le mieux quand on a besoin de toutes les lignes mais veut toujours la fonction d'agrégation en fonction d'un groupe.

Bien sûr, il pourrait aussi y avoir des problèmes de performance, voir http://social.msdn.microsoft.com/Forums/ms-MY/transactsql/thread/0b20c2b5-1607-40bc-b7a7-0c60a2a55fba .

Supposons que nous ayons 14 dossiers de colonne name 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 i.e. 14

mais dans partition by

select row_number() over (partition by name) as total from person where name = 'Please fill out';

il sera 14 lignes d'augmentation du nombre

observation petite. mécanisme d'automatisation pour générer dynamiquement SQL en utilisant la « partition par » il est beaucoup plus simple à mettre en œuvre en relation avec le « groupe par ». Dans le cas du « groupe par », nous devons prendre soin du contenu de la colonne « select ».

Désolé pour mon anglais.

Il a vraiment différents scénarios d'utilisation. Lorsque vous utilisez GROUP BY vous fusionnez certains des enregistrements pour les colonnes qui sont identiques et vous avez une agrégation de l'ensemble de résultats.

Toutefois, lorsque vous utilisez PARTITION BY votre jeu de résultats est la même, mais vous avez juste une agrégation sur les fonctions de la fenêtre et vous ne fusionnez pas les enregistrements, vous aurez toujours le même nombre d'enregistrements.

Voici un rassemblement article expliquant la différence utile: http://alevryustemov.com/sql/sql-partition-by/

-- 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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top