Recherche…


Groupement simple

Tableau des commandes

N ° de client ProductId Quantité Prix
1 2 5 100
1 3 2 200
1 4 1 500
2 1 4 50
3 5 6 700

Lors du regroupement par une colonne spécifique, seules les valeurs uniques de cette colonne sont renvoyées.

SELECT customerId
FROM orders
GROUP BY customerId;

Valeur de retour:

N ° de client
1
2
3

Les fonctions d'agrégat comme count() s'appliquent à chaque groupe et non à la table complète:

SELECT customerId, 
       COUNT(productId) as numberOfProducts,
       sum(price) as totalPrice
FROM orders
GROUP BY customerId;

Valeur de retour:

N ° de client nombreProduits prix total
1 3 800
2 1 50
3 1 700

GROUP BY plusieurs colonnes

On peut vouloir grouper par plus d'une colonne

declare @temp table(age int, name varchar(15))

insert into @temp
select 18, 'matt' union all
select 21, 'matt' union all
select 21, 'matt' union all
select 18, 'luke' union all
select 18, 'luke' union all
select 21, 'luke' union all
select 18, 'luke' union all
select 21, 'luke'

SELECT Age, Name, count(1) count
FROM @temp 
GROUP BY Age, Name

regroupera par âge et par nom et produira:

Âge prénom compter
18 Luke 3
21 Luke 2
18 mat 1
21 mat 2

Regrouper avec plusieurs tables, plusieurs colonnes

Group by est souvent utilisé avec une déclaration de jointure. Supposons que nous ayons deux tables. Le premier est la table des étudiants:

Id Nom complet Âge
1 Matt Jones 20
2 Frank Blue 21
3 Anthony Angel 18

Le deuxième tableau est la table des matières que chaque élève peut prendre:

Subject_Id Assujettir
1 Mathématiques
2 PE
3 La physique

Et comme un étudiant peut participer à de nombreuses matières et qu'un sujet peut être suivi par de nombreux étudiants (donc une relation N: N), nous devons avoir un troisième tableau "limite". Appelons la table Students_subjects:

Subject_Id Carte d'étudiant
1 1
2 2
2 1
3 2
1 3
1 1

Maintenant, disons que nous voulons connaître le nombre de sujets que chaque étudiant fréquente. Ici, l'instruction GROUP BY autonome n'est pas suffisante car les informations ne sont pas disponibles via une seule table. Par conséquent, nous devons utiliser GROUP BY avec l'instruction JOIN :

Select Students.FullName, COUNT(Subject Id) as SubjectNumber FROM Students_Subjects
LEFT JOIN Students
ON Students_Subjects.Student_id = Students.Id
GROUP BY Students.FullName

Le résultat de la requête donnée est le suivant:

Nom complet Numéro d'objet
Matt Jones 3
Frank Blue 2
Anthony Angel 1

Pour un exemple encore plus complexe de l'utilisation de GROUP BY, supposons que l'élève puisse assigner le même sujet à son nom plus d'une fois (comme indiqué dans le tableau Students_Subjects). Dans ce scénario, nous pourrions être en mesure de compter le nombre de fois que chaque sujet a été attribué à un élève par GROUPing par plus d'une colonne:

SELECT Students.FullName, Subjects.Subject,
COUNT(Students_subjects.Subject_id) AS NumberOfOrders
FROM ((Students_Subjects
INNER JOIN Students
ON Students_Subjcets.Student_id=Students.Id)
INNER JOIN Subjects
ON Students_Subjects.Subject_id=Subjects.Subject_id)
GROUP BY Fullname,Subject

Cette requête donne le résultat suivant:

Nom complet Assujettir Numéro d'objet
Matt Jones Mathématiques 2
Matt Jones PE 1
Frank Blue PE 1
Frank Blue La physique 1
Anthony Angel Mathématiques 1

AYANT

Étant donné que la clause WHERE est évaluée avant GROUP BY , vous ne pouvez pas utiliser WHERE pour réduire les résultats du regroupement (généralement une fonction d'agrégat, telle que COUNT(*) ). Pour répondre à ce besoin, la clause HAVING peut être utilisée.

Par exemple, en utilisant les données suivantes:

DECLARE @orders TABLE(OrderID INT, Name NVARCHAR(100))

INSERT INTO @orders VALUES
( 1, 'Matt' ),
( 2, 'John' ),
( 3, 'Matt' ),
( 4, 'Luke' ),
( 5, 'John' ),
( 6, 'Luke' ),
( 7, 'John' ),
( 8, 'John' ),
( 9, 'Luke' ),
( 10, 'John' ),
( 11, 'Luke' )

Si nous voulons obtenir le nombre de commandes que chaque personne a passées, nous utiliserons

SELECT Name, COUNT(*) AS 'Orders'
FROM @orders
GROUP BY Name

et obtenir

prénom Ordres
Mat 2
John 5
Luke 4

Cependant, si nous voulons limiter cela aux individus qui ont placé plus de deux ordres, nous pouvons ajouter une clause HAVING .

SELECT Name, COUNT(*) AS 'Orders'
FROM @orders
GROUP BY Name
HAVING COUNT(*) > 2

va céder

prénom Ordres
John 5
Luke 4

Notez que, tout comme GROUP BY , les colonnes placées dans HAVING doivent correspondre exactement à leurs homologues dans l' SELECT . Si dans l'exemple ci-dessus, nous avions plutôt dit

SELECT Name, COUNT(DISTINCT OrderID)

notre clause HAVING devrait dire

HAVING COUNT(DISTINCT OrderID) > 2

GROUP BY avec ROLLUP et CUBE

L'opérateur ROLLUP est utile pour générer des rapports contenant des sous-totaux et des totaux.

  • CUBE génère un jeu de résultats qui affiche des agrégats pour toutes les combinaisons de valeurs dans les colonnes sélectionnées.

  • ROLLUP génère un jeu de résultats qui affiche des agrégats pour une hiérarchie de valeurs dans les colonnes sélectionnées.

    Article Couleur Quantité
    Table Bleu 124
    Table rouge 223
    chaise Bleu 101
    chaise rouge 210
SELECT CASE WHEN (GROUPING(Item) = 1) THEN 'ALL'
            ELSE ISNULL(Item, 'UNKNOWN')
       END AS Item,
       CASE WHEN (GROUPING(Color) = 1) THEN 'ALL'
            ELSE ISNULL(Color, 'UNKNOWN')
       END AS Color,
       SUM(Quantity) AS QtySum
FROM Inventory
GROUP BY Item, Color WITH ROLLUP

Item                 Color                QtySum                     
-------------------- -------------------- -------------------------- 
Chair                Blue                 101.00                     
Chair                Red                  210.00                     
Chair                ALL                  311.00                     
Table                Blue                 124.00                     
Table                Red                  223.00                     
Table                ALL                  347.00                     
ALL                  ALL                  658.00 

(7 rangs affectés)

Si le mot clé ROLLUP de la requête est remplacé par CUBE, le jeu de résultats CUBE est identique, sauf que ces deux lignes supplémentaires sont renvoyées à la fin:

ALL                  Blue                 225.00                     
ALL                  Red                  433.00 

https://technet.microsoft.com/en-us/library/ms189305(v=sql.90).aspx



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