Recherche…


Introduction

Les résultats d'une requête SELECT peuvent être regroupés par une ou plusieurs colonnes à l'aide de l'instruction GROUP BY : tous les résultats ayant la même valeur dans les colonnes groupées sont regroupés. Cela génère une table de résultats partiels, au lieu d'un résultat. GROUP BY peut être utilisé conjointement avec les fonctions d'agrégation à l'aide de l'instruction HAVING pour définir la manière dont les colonnes non groupées sont agrégées.

Syntaxe

  • PAR GROUPE {
    expression de colonne
    | ROLLUP (<group_by_expression> [, ... n])
    | CUBE (<expression_de_groupe> [, ... n])
    | GROUPING SETS ([, ... n])
    | () calcule le total général
    } [, ... n]

  • <group_by_expression> :: =
    expression de colonne
    | (expression de colonne [, ... n])

  • <grouping_set> :: =
    () calcule le total général
    | <grouping_set_item>
    | (<grouping_set_item> [, ... n])

  • <grouping_set_item> :: =
    <group_by_expression>
    | ROLLUP (<group_by_expression> [, ... n])
    | CUBE (<expression_de_groupe> [, ... n])

UTILISEZ GROUP BY pour COUNT le nombre de lignes pour chaque entrée unique dans une colonne donnée

Supposons que vous souhaitiez générer des comptes ou des sous-totaux pour une valeur donnée dans une colonne.

Compte tenu de ce tableau, "Westerosians":

prénom GreatHouseAllegience
Arya Rigide
Cercei Lannister
Myrcella Lannister
Yara Greyjoy
Catelyn Rigide
Sansa Rigide

Sans GROUP BY, COUNT retournera simplement un nombre total de lignes:

SELECT Count(*) Number_of_Westerosians
FROM Westerosians

résultats...

Number_of_Westerosians
6

Mais en ajoutant GROUP BY, nous pouvons COMPTER les utilisateurs pour chaque valeur dans une colonne donnée, pour retourner le nombre de personnes dans une Grande Maison donnée, par exemple:

SELECT GreatHouseAllegience House, Count(*) Number_of_Westerosians
FROM Westerosians
GROUP BY GreatHouseAllegience

résultats...

Maison Number_of_Westerosians
Rigide 3
Greyjoy 1
Lannister 2

Il est courant de combiner GROUP BY avec ORDER BY pour trier les résultats par catégorie la plus grande ou la plus petite:

SELECT GreatHouseAllegience House, Count(*) Number_of_Westerosians
FROM Westerosians
GROUP BY GreatHouseAllegience
ORDER BY Number_of_Westerosians Desc

résultats...

Maison Number_of_Westerosians
Rigide 3
Lannister 2
Greyjoy 1

Filtrez les résultats de GROUP BY en utilisant une clause HAVING

Une clause HAVING filtre les résultats d'une expression GROUP BY. Remarque: Les exemples suivants utilisent la base de données exemple de la bibliothèque .

Exemples:

Renvoie tous les auteurs ayant écrit plus d'un livre ( exemple en direct ).

SELECT
  a.Id,
  a.Name,
  COUNT(*) BooksWritten
FROM BooksAuthors ba
  INNER JOIN Authors a ON a.id = ba.authorid
GROUP BY
  a.Id,
  a.Name
HAVING COUNT(*) > 1    -- equals to HAVING BooksWritten > 1
;

Retourne tous les livres qui ont plus de trois auteurs ( exemple live ).

SELECT
  b.Id,
  b.Title,
  COUNT(*) NumberOfAuthors
FROM BooksAuthors ba
  INNER JOIN Books b ON b.id = ba.bookid
GROUP BY
  b.Id,
  b.Title
HAVING COUNT(*) > 3    -- equals to HAVING NumberOfAuthors > 3
;

Exemple de GROUP BY de base

Cela pourrait être plus facile si vous considérez GROUP BY comme "pour chacun" pour des raisons d'explication. La requête ci-dessous:

SELECT EmpID, SUM (MonthlySalary) 
FROM Employee
GROUP BY EmpID

Est en train de dire:

"Donnez-moi la somme de MonthlySalary's pour chaque EmpID"

Donc, si votre table ressemblait à ceci:

+-----+-------------+
|EmpID|MonthlySalary|
+-----+-------------+
|1    |200          |
+-----+-------------+
|2    |300          |
+-----+-------------+

Résultat:

+-+---+
|1|200|
+-+---+
|2|300|
+-+---+

Sum ne semble rien faire car la somme d'un nombre est ce nombre. Par contre si ça ressemblait à ça:

+-----+-------------+
|EmpID|MonthlySalary|
+-----+-------------+
|1    |200          |
+-----+-------------+
|1    |300          |
+-----+-------------+
|2    |300          |
+-----+-------------+

Résultat:

+-+---+
|1|500|
+-+---+
|2|300|
+-+---+

Alors ce serait parce qu'il y a deux EmpID 1 à résumer ensemble.

Agrégation ROLAP (Data Mining)

La description

Le standard SQL fournit deux opérateurs d'agrégat supplémentaires. Ceux-ci utilisent la valeur polymorphe "ALL" pour désigner l'ensemble de toutes les valeurs qu'un attribut peut prendre. Les deux opérateurs sont:

  • with data cube qu'il fournit toutes les combinaisons possibles aux attributs d'argument de la clause.
  • with roll up qu'il fournit les agrégats obtenus en considérant les attributs dans l'ordre de gauche à droite par rapport à la façon dont ils sont listés dans l'argument de la clause.

Versions standard SQL qui prennent en charge ces fonctionnalités: 1999,2003,2006,2008,2011.

Exemples

Considérez ce tableau:

Aliments Marque Montant total
Pâtes Marque1 100
Pâtes Marque2 250
Pizza Marque2 300

Avec cube

select Food,Brand,Total_amount
from Table
group by Food,Brand,Total_amount with cube
Aliments Marque Montant total
Pâtes Marque1 100
Pâtes Marque2 250
Pâtes TOUT 350
Pizza Marque2 300
Pizza TOUT 300
TOUT Marque1 100
TOUT Marque2 550
TOUT TOUT 650

Avec roll up

select Food,Brand,Total_amount
from Table
group by Food,Brand,Total_amount with roll up
Aliments Marque Montant total
Pâtes Marque1 100
Pâtes Marque2 250
Pizza Marque2 300
Pâtes TOUT 350
Pizza TOUT 300
TOUT TOUT 650


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow