Microsoft SQL Server
PAR GROUPE
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