Cours SQL ORACLE – 05 : GROUP BY HAVING
Dans ce nouveau chapitre, nous allons nous attaquer à la clause GROUP BY. Pour mieux expliquer cette clause, prenons l’exemple suivant :
Dans la table EMP du schéma SCOTT, nous voulons afficher la somme des salaires (SAL) pour chaque poste (JOB). Dans cette requête nous avons besoin de grouper les données par poste pour faire la somme des salaires de chaque poste :
SELECT JOB, SUM(SAL) FROM EMP
GROUP BY JOB;
JOB SUM(SAL)
--------- ----------------------
CLERK 4150
SALESMAN 5600
PRESIDENT 5000
MANAGER 8275
ANALYST 6000
Comme vous pouvez le voir dans le résultat, pour chaque JOB de la table EMP, nous avons affiché la somme des SAL correspondant.
Nous pouvons grouper autant de colonne que nous voulons, par exemple, nous voulons afficher la moyenne des SAL pour chaque JOB et MGR et nous allons ordonner le résultat par JOB, MGR et par la moyenne des SAL :
SELECT JOB, MGR, AVG(SAL) FROM EMP
GROUP BY JOB, MGR
ORDER BY 1, 2, 3;
JOB MGR AVG(SAL)
--------- ---------------------- ----------------------
ANALYST 7566 3000
CLERK 7698 950
CLERK 7782 1300
CLERK 7788 1100
CLERK 7902 800
MANAGER 7839 2758,33
PRESIDENT 5000
SALESMAN 7698 1400
Vous pouvez constater que les colonnes sélectionnées sont ceux avec quoi nous regroupons, et que chaque ligne affichée est unique.
Nous pouvons utiliser le WHERE avec GROUP BY comme suit : nous voulons afficher le salaire MAX par ville :
SELECT LOC, MAX(SAL) FROM EMP, DEPT
WHERE EMP.DEPTNO = DEPT.DEPTNO
GROUP BY LOC;
LOC MAX(SAL)
------------- ----------------------
NEW YORK 5000
CHICAGO 2850
DALLAS 3000
Essayons maintenant de sélectionner les villes avec un salaire max supérieur ou égal à 3000
SELECT LOC, MAX(SAL) FROM EMP, DEPT
WHERE EMP.DEPTNO = DEPT.DEPTNO
GROUP BY LOC
HAVING MAX(SAL) >= 3000;
LOC MAX(SAL)
------------- ----------------------
NEW YORK 5000
DALLAS 3000
On utilise HAVING pour faire un filtre sur les données du GROUP BY.
Nous pouvons, par exemple avec la requête GROUP BY, détecter les lignes redondantes d’une table ou d’une sélection : nous allons afficher dans la requête suivante les MGR qui sont des managers de plus d’une personne
SELECT MGR, COUNT(*)
FROM EMP
GROUP BY MGR
HAVING COUNT(*) > 1;
MGR COUNT(*)
---------------------- ----------------------
7839 3
7698 5
7566 2
Ce qu’il faut retenir c’est:
- Les colonnes sélectionnées doivent être les même dans le GROUP BY.
- Le WHERE doit être utilisé avant la clause GROUP BY, alors que HAVING vient après.
- Nous pouvons utiliser avec le GROUP BY plusieurs fonctions d’agrégations.