Télécharger la présentation
La présentation est en train de télécharger. S'il vous plaît, attendez
Publié parFabien Marc-Antoine Boutin Modifié depuis plus de 6 années
1
Langage d’interrogation des Données Les fonctions de groupes
Année universitaire 2017/2018 LFIG 2 Langage d’interrogation des Données Les fonctions de groupes Fahmi Ben Rejab
2
Les fonctions de groupes
Dans les exemples précédents, chaque ligne résultat d'un SELECT était le résultat de calculs sur les valeurs d'une seule ligne de la table consultée. Il existe un autre type de SELECT qui permet d'effectuer des calculs sur l'ensemble des valeurs d'une colonne. Ces calculs sur l'ensemble des valeurs d'une colonne se font au moyen de l'une des fonctions suivantes : AVG([DISTINCT | ALL] expression) Renvoie la moyenne des valeurs d'expression. COUNT(* | [DISTINCT | ALL] expression) Renvoie le nombre de lignes du résultat de la requête. Si expression est présent, on ne compte que les lignes pour lesquelles cette expression n'est pas NULL. MAX([DISTINCT | ALL] expression) Renvoie la plus grande des valeurs d'expression.
3
Les fonctions de groupes
MIN([DISTINCT | ALL] expression) Renvoie la plus petite des valeurs d'expression. STDDEV([DISTINCT | ALL] expression) Renvoie l'écart-type des valeurs d'expression. SUM([DISTINCT | ALL] expression) Renvoie la somme des valeurs VARIANCE([DISTINCT | ALL] expression) Renvoie la variance des valeurs d'expression. DISTINCT Indique à la fonction de groupe de ne prendre en compte que des valeurs distinctes. ALL Indique à la fonction de groupe de prendre en compte toutes les valeurs.
4
Exemples Exemple : Donner le total des salaires du département 10.
SELECT SUM(sal) FROM emp WHERE deptno = 10; Exemple : Donner le nom, la fonction et le salaire de l'employé (ou des employés) ayant le salaire le plus élevé. SELECT ename, job, sal WHERE sal = (SELECT MAX(sal) FROM emp);
5
Les fonctions de groupes
Remarques Ces SELECT sont différents de ceux vus précédemment. Il est, par exemple, impossible de demander en résultat à la fois une colonne et une fonction de groupe. Un SELECT comportant une fonction de groupe peut être utilisé dans une sous-interrogation. SUM(col) est la somme des valeurs non NULL de la colonne col. De même AVG est la somme des valeurs non NULL divisée par le nombre de valeurs non NULL.
6
Group by Il est possible de subdiviser la table en groupes, chaque groupe étant l'ensemble des lignes ayant une valeur commune. C'est la clause GROUP BY qui permet de découper la table en plusieurs groupes : GROUP BY expr_1, expr_2, ... Si on a une seule expression, ceci définit les groupes comme les ensembles de lignes pour lesquelles cette expression prend la même valeur. Si plusieurs expressions sont présentes les groupes sont définis de la façon suivante : parmi toutes les lignes pour lesquelles expr_1 prend la même valeur, on regroupe celles ayant expr_2 identique, ... Un SELECT de groupe avec une clause GROUP BY donnera une ligne résultat pour chaque groupe.
7
Group by Exemple : Total des salaires pour chaque département
SELECT deptno , SUM(sal) sal FROM emp GROUP BY deptno; Remarque : Dans la liste des colonnes résultat d'un SELECT comportant une fonction de groupe, ne peuvent figurer que des caractéristiques de groupe, c'est-à-dire : soit des fonctions de groupe ; soit des expressions figurant dans le GROUP BY.
8
Group by & Having De la même façon qu'il est possible de sélectionner certaines lignes au moyen de la clause WHERE, il est possible dans un SELECT comportant une fonction de groupe de sélectionner par la clause HAVING, qui se place après la clause GROUP BY. Le prédicat dans la clause HAVING suit les mêmes règles de syntaxe qu'un prédicat figurant dans une clause WHERE. Cependant, il ne peut porter que sur des caractéristiques du groupe : fonction de groupe ou expression figurant dans la clause GROUP BY, dans ce cas la clause HAVING doit être placée après la clause GROUP BY.
9
Sélection des groupes Exemple : Donner la liste des salaires moyens par fonction pour les groupes ayant plus de deux employés. SELECT job, COUNT(*), AVG(sal) FROM emp GROUP BY job HAVING COUNT(*) > 2; Remarque : Un SELECT de groupe peut contenir à la fois une clause WHERE et une clause HAVING. La clause WHERE sera d'abord appliquée pour sélectionner les lignes, puis les groupes seront constitués à partir des lignes sélectionnées, et les fonctions de groupe seront évaluées.
10
Sélection des groupes Exemple : Donner le nombre d'ingénieurs ou de commerciaux des départements ayant au moins deux employés de ces catégories. SELECT deptno, COUNT(*) FROM emp WHERE job in (‘manager',’CLERCK') GROUP BY deptno HAVING COUNT(*) >= 2;
11
Sélection des groupes Une clause HAVING peut comporter une sous-interrogation. Exemple : Quel est le département ayant le plus d'employés? SELECT deptno,COUNT(*) FROM emp GROUP BY deptno HAVING COUNT(*) = (SELECT MAX(COUNT(*)) FROM emp GROUP BY deptno) ;
12
Fonction de groupe à deux niveaux
Il est possible d'appliquer au résultat d'un SELECT avec GROUP BY un deuxième niveau de fonction de groupe. Exemple : la fonction MAX peut être appliquée aux nombres d'employés de chaque département pour obtenir le nombre d'employés du département ayant le plus d'employés. SELECT MAX(COUNT(*)) FROM emp GROUP BY deptno;
13
La DIVISION La division est l'une des huit opérations de base de l'algèbre relationnel. N'est pas implémentée au sein du standard SQL L'idée générale à la division est de partir d'une table dividende que l'on divise à l'aide d'une table diviseur pour obtenir un quotient. Le résultat est calculé à partir des valeurs d'une colonne pour lesquelles la seconde colonne de la table dividende possèdent toutes les valeurs du diviseur. La division relationnelle est capable de répondre à des questions aussi simples que : quels sont les clients qui sont abonnés à tous les magazines d'un éditeur ? Le concept est a priori est simple, mais son implémentation à l'aide du SQL n'est pas si facile...
14
La DIVISION PROJECTION SELECT [ALL] [DISTINCT] liste d'attributs
FROM table SELECTION SELECT liste d'attributs WHERE condition
15
La DIVISION JOINTURE SELECT liste d'attributs
FROM table1 JOIN table2 ON table1.attribut1=table2.attribut1 ... OU FROM table1,table2 Where table1.attribut1=table2.attribut1 ... UNION SELECT liste d'attributs FROM table
16
La DIVISION INTERSECTION SELECT liste d'attributs FROM table INTERSECT
on peut aussi utiliser une clause WHERE avec le NOT IN SELECT liste d'attributs FROM table1 WHERE attribut1 NOT IN SELECT liste d'attributs FROM table2 DIFFERENCE Minus
17
La DIVISION PRODUIT SELECT * FROM table1, table2 (pas de where)
ou encore SELECT * FROM table1 CROSS JOIN table2 DIVISION ????????????????????
18
La DIVISION Exemple: Nous sommes dans une entreprise de la grande distribution possédant des entrepôts dans différentes villes de France. Ces entrepôts peuvent avoir les produits de différents rayons. La question est : quels sont les entrepôts capables de servir TOUS les rayons ? Bien entendu nous avons une table des entrepôts et une autres des rayons...
19
La DIVISION Rien de plus simple que de visualiser la réponse : il suffit de trouver les entrepôts qui sont reliés à TOUS les rayons. La réponse est ici évidente, seule TOULOUSE et MARSEILLE satisfont aux critères de la question (comme quoi, le sud est en avance sur le nord dans notre exemple !).
20
La DIVISION voici le script de création de la base de données et des données /* LA DIVISION RELATIONNELLE*/ /***********************/ /* CRÉATION DES TABLES */ CREATE TABLE T_RAYON ( RAYON_RYN CHAR(16) ) /* tables des entrepôts */ CREATE TABLE T_ENTREPOT ( VILLE_ETP CHAR(16), RAYON_RYN CHAR(16) ) /***************************/ /* alimentation de la table des rayons */ INSERT INTO T_RAYON (RAYON_RYN) VALUES (‘frais’) INSERT INTO T_RAYON (RAYON_RYN) VALUES (‘boisson’) INSERT INTO T_RAYON (RAYON_RYN) VALUES (‘conserve’) INSERT INTO T_RAYON (RAYON_RYN) VALUES (‘droguerie’) /* alimentation de la table des entrepots */ INSERT INTO T_ENTREPOT (VILLE_ETP, RAYON_RYN) VALUES (‘PARIS’, ‘boisson’) INSERT INTO T_ENTREPOT (VILLE_ETP, RAYON_RYN) VALUES (‘PARIS’, ‘frais’) INSERT INTO T_ENTREPOT (VILLE_ETP, RAYON_RYN) VALUES (‘PARIS’, ‘conserve’) INSERT INTO T_ENTREPOT (VILLE_ETP, RAYON_RYN) VALUES (‘LYON’, ‘boisson’) INSERT INTO T_ENTREPOT (VILLE_ETP, RAYON_RYN) VALUES (‘LYON’, ‘conserve’) INSERT INTO T_ENTREPOT (VILLE_ETP, RAYON_RYN) VALUES (‘LYON’, ‘droguerie’) INSERT INTO T_ENTREPOT (VILLE_ETP, RAYON_RYN) VALUES (‘MARSEILLE’, ‘boisson’) INSERT INTO T_ENTREPOT (VILLE_ETP, RAYON_RYN) VALUES (‘MARSEILLE’, ‘frais’) INSERT INTO T_ENTREPOT (VILLE_ETP, RAYON_RYN) VALUES (‘MARSEILLE’, ‘conserve’) INSERT INTO T_ENTREPOT (VILLE_ETP, RAYON_RYN) VALUES (‘MARSEILLE’, ‘droguerie’) INSERT INTO T_ENTREPOT (VILLE_ETP, RAYON_RYN) VALUES (‘ANGER’, ‘boisson’) INSERT INTO T_ENTREPOT (VILLE_ETP, RAYON_RYN) VALUES (‘ANGER’, ‘frais’) INSERT INTO T_ENTREPOT (VILLE_ETP, RAYON_RYN) VALUES (‘ANGER’, ‘droguerie’) INSERT INTO T_ENTREPOT (VILLE_ETP, RAYON_RYN) VALUES (‘TOULOUSE’, ‘boisson’) INSERT INTO T_ENTREPOT (VILLE_ETP, RAYON_RYN) VALUES (‘TOULOUSE’, ‘frais’) INSERT INTO T_ENTREPOT (VILLE_ETP, RAYON_RYN) VALUES (‘TOULOUSE’, ‘conserve’) INSERT INTO T_ENTREPOT (VILLE_ETP, RAYON_RYN) VALUES (‘TOULOUSE’, ‘droguerie’)
21
La DIVISION
22
La DIVISION Qui donne pour résultat : MARSEILLE, TOULOUSE
Une première implémentation qui vient immédiatement à l'esprit est de compter le nombre d'occurrences des rayons et de le faire coïncider avec le dénombrement des rayons des différents entrepôts : SELECT VILLE_ETP FROM T_ENTREPOT GROUP BY VILLE_ETP HAVING COUNT(*) = (SELECT COUNT(*) FROM T_RAYON) Qui donne pour résultat : MARSEILLE, TOULOUSE Cette solution, apparemment bonne, ne marche que dans des cas relativement limités : lorsqu'il n'y a aucune redondance de données dans la table diviseur lorsqu'il n'y a pas de rayon en sus pour un entrepôt, non recensé dans la table T_ENTREPOT
23
La DIVISION Pour éviter la redondance SELECT VILLE_ETP FROM T_ENTREPOT
GROUP BY VILLE_ETP HAVING COUNT(*) = (SELECT COUNT(DISTINCT RAYON_RYN) FROM T_RAYON) Solution idéale SELECT VILLE_ETP FROM T_ENTREPOT WHERE RAYON_RYN IN (SELECT RAYON_RYN FROM T_RAYON) GROUP BY VILLE_ETP HAVING COUNT(*) = (SELECT COUNT(DISTINCT RAYON_RYN) FROM T_RAYON)
Présentations similaires
© 2024 SlidePlayer.fr Inc.
All rights reserved.