Cours 4

Transcription

Cours 4
Cours 4 : Agrégats et
GROUP BY
Agrégat
Fonction qui effectue un calcul sur
l’ensemble des valeurs d’un attribut
pour un groupe de lignes
Utilisation dans une clause SELECT ou
dans une clause HAVING
3 types d’agrégats :
• MIN, MAX
• SUM, AVG, VARIANCE, STDDEV
• COUNT
2013-2014
Bases de données
2
Agrégat sur un seul group
Un seul groupe constitué de l’ensemble des
lignes sélectionnées par une éventuelle
clause WHERE
Syntaxe :
SELECT
aggregat1 ([DISTINCT] expression1), ...
aggregatn ([DISTINCT] expressionn)
FROM noms-tables
[WHERE conditions]
2013-2014
Bases de données
3
Exemple
SELECT MIN(prix) AS prixMin,
MAX(prix) AS prixMax
FROM Tarif
2013-2014
Bases de données
4
Exemple (2)
SELECT MIN(nomVille),
MAX(nomville)
FROM Ville
2013-2014
Bases de données
5
Exemple (3)
SELECT MIN(dateDeb),
MAX(dateDeb)
FROM Tarif
WHERE numVoyage = 4
2013-2014
Bases de données
6
Exemple (4)
SELECT AVG(prix)
FROM Tarif
WHERE numVoyage = 4
SELECT AVG(DISTINCT prix),
FROM Tarif
WHERE numVoyage = 4
2013-2014
Bases de données
7
Exemple (5)
numVoyage
nomVoyage
nbMin nbMax typePension
1
Circuit Heleni
15
P
4
Rhapsodie hongroise
15
40
P
Budapest, Vienne
5
20
DP
et Prague
6
Arménie et Géorgie
15
30
P
VOYAGE
SELECT COUNT(*)FROM Voyage
2013-2014
Bases de données
4
8
Exemple (6)
numVoyage
nomVoyage
nbMin nbMax typePension
1
Circuit Heleni
15
P
4
Rhapsodie hongroise
15
40
P
Budapest, Vienne
5
20
DP
et Prague
6
Arménie et Géorgie
15
30
P
VOYAGE
SELECT COUNT(nbMax)FROM Voyage
2013-2014
Bases de données
2
9
Exemple (7)
numVoyage
nomVoyage
nbMin nbMax typePension
1
Circuit Heleni
15
P
4
Rhapsodie hongroise
15
40
P
Budapest, Vienne
5
20
DP
et Prague
6
Arménie et Géorgie
15
30
P
VOYAGE
SELECT COUNT(DISTINCT typePension)
FROM Voyage
2013-2014
Bases de données
2
10
Agrégats sur un seul groupe
(suite)
Les valeurs NULL sont ignorées par les
agrégats
Un agrégat ne peut apparaître dans une
clause WHERE (sauf dans un sousselect)
Il est impossible de demander en
résultat à la fois un attribut et un
agrégat
2013-2014
Bases de données
11
Exemple
SELECT COUNT(*), numVoyage
FROM Voyage
FAUX
ERROR at line 1 :
ORA-000937 : not a singlegroup group function
2013-2014
Bases de données
12
Groupements
Pour subdiviser les lignes résultats d’un
ordre SELECT en plusieurs groupes il
faut utiliser une clause GROUP BY
Un groupe est formé d’un ensemble de
lignes ayant une ou plusieurs
caractéristiques communes
Il y a autant de groupes que de valeurs
distinctes des caractéristiques décrites
pour la formation des groupes
2013-2014
Bases de données
13
Groupements (suite)
Un ordre SELECT avec une clause GROUP BY
donne une ligne résultat pour chaque groupe
Syntaxe :
SELECT * | [DISTINCT] liste-attributs
FROM noms-tables
[WHERE conditions]
[GROUP BY liste-expressions]
[HAVING conditions]
[ORDER BY liste-critères]
2013-2014
Bases de données
14
Questions
Donner, pour
chaque voyage, sa
durée totale ainsi
que son nombre
d’étapes
ETAPE
numVoyage
1
1
4
4
4
4
5
5
numVille
1
5
7
7
8
9
7
10
numOrdre
1
2
1
4
2
3
2
1
duree
3
1
3
1
2
1
3
3
5
5
5
6
6
6
6
6
11
12
13
14
14
15
16
17
3
4
5
1
5
2
3
4
1
4
1
5
1
2
2
1
Questions (2)
Donner, pour
chaque voyage, sa
durée totale ainsi
que son nombre
d’étapes
numVoyage durée totale nb étapes
1
4
2
4
7
4
RESULTAT DE LA REQUETE
5
12
5
6
11
5
2013-2014
Bases de données
16
Questions (3)
Donner, pour chaque voyage, sa durée
totale ainsi que son nombre d’étapes
SELECT numVoyage,
SUM(duree) AS "durée totale",
COUNT(*) AS "nb étapes"
FROM Etape
GROUP BY numVoyage
2013-2014
Bases de données
17
Questions (4)
... pour les voyages de numéro supérieur à
5 et ayant plus de 3 étapes
SELECT numVoyage,
SUM(duree) AS "durée totale",
COUNT(*) AS "nb étapes"
FROM Etape
WHERE numVoyage > 5
GROUP BY numVoyage
HAVING COUNT(*) > 3
2013-2014
Bases de données
18
Très important
Dans la liste des attributs d’un ordre
SELECT avec une clause GROUP BY ne
peuvent figurer que des caractéristiques
de groupe, c’est-à-dire :
• Soit des agrégats
• Soit des expressions figurant dans la
clause GROUP BY
2013-2014
Bases de données
19
Exemple
SELECT numVoyage,
MIN(dateDeb),
prix
FROM Tarif
GROUP BY numVoyage
FAUX
2013-2014
Bases de données
20
Exemple (2)
SELECT numVoyage,
MIN(dateDeb)
FROM Tarif
GROUP BY numVoyage
JUSTE
2013-2014
Bases de données
21
Exemple (3)
SELECT numVoyage,
MIN(dateDeb),
prix
FROM Tarif
GROUP BY numVoyage, prix
JUSTE
2013-2014
Bases de données
22
HAVING
De même qu’il est possible de
sélectionner certaines lignes avec une
clause WHERE, il est possible de
sélectionner certains groupes de lignes
en utilisant une clause HAVING
Les conditions figurant dans la clause
HAVING suivent les mêmes règles de
syntaxe que celles d’une clause WHERE
2013-2014
Bases de données
23
HAVING (suite)
Les conditions figurant dans la clause
HAVING ne peuvent porter que sur les
caractéristiques du
groupe : agrégats ou expression
contenues dans la clause GROUP BY
Une clause HAVING peut comporter un
sous-select
2013-2014
Bases de données
24
Exemple
SELECT numVoyage, AVG(prix)
FROM Tarif
WHERE dateDeb >= '01-01-14'
GROUP BY numVoyage
HAVING AVG(prix) >=
(SELECT AVG(prix) FROM Tarif
WHERE dateDeb >= '01-01-14')
2013-2014
Bases de données
25
Plan d’exécution
Si un SELECT comporte à la fois une
clause WHERE et une clause GROUP BY :
• la clause WHERE sera d’abord utilisée pour
sélectionner les lignes
• les groupes seront constitués à partir des
lignes sélectionnées
• les groupes seront alors eux-mêmes
sélectionnés par la clause HAVING
2013-2014
Bases de données
26
Niveaux d’agrégats
Il est possible d’appliquer au résultat
d’un SELECT avec GROUP BY un second
niveau de fonction de groupe
2013-2014
Bases de données
27
Exemple
SELECT MAX(COUNT(*))
FROM Voyage
GROUP BY typePension
numVoyage
nomVoyage
nbMin nbMax typePension
1
Circuit Heleni
15
P
4
Rhapsodie hongroise
15
40
P
Budapest, Vienne
5
20
DP
et Prague
6
Arménie et Géorgie
15
30
P
VOYAGE
2013-2014
Bases de données
28
Exemple (2)
SELECT COUNT(*)
FROM Voyage
GROUP BY typePension
COUNT(*)
3
1
RESULTAT DE LA REQUETE
On demande le maximum ensuite
2013-2014
Bases de données
29
Questions
Nombre de départs pour chacun des
voyages dont le nom commence par ‘C’ ou
par ‘R’ ?
SELECT V.numVoyage, COUNT(*)
FROM Voyage V, Tarif T
WHERE V.numVoyage = T.numVoyage
AND (nomVoyage LIKE 'C%'
OR nomVoyage LIKE 'R%')
GROUP BY V.numVoyage
2013-2014
Bases de données
30
Questions (2)
Nombre de départs pour chacun des
voyages dont le nom commence par ‘C’ ou
par ‘R’ ?
numVoyage
nomVoyage
nbMin nbMax typePension
1
Circuit Heleni
15
P
4
Rhapsodie hongroise
15
40
P
Budapest, Vienne
5
20
DP
et Prague
6
Arménie et Géorgie
15
30
P
VOYAGE
2013-2014
Bases de données
31
Questions (3)
Nombre de départs pour chacun des
voyages dont le nom commence par ‘C’ ou
par ‘R’ ?
numVoyage
1
1
1
4
5
2013-2014
dateDeb
25-09-14
02-09-14
09-09-14
16-09-14
09-09-14
TARIF
Bases de données
prix
690
680
680
790
1400
32
Questions (4)
Nombre de départs pour chacun des
voyages dont le nom commence par ‘C’ ou
par ‘R’ ?
numVoyage
1
1
1
4
5
2013-2014
nomVoyage
nbMin nbMax typePension dateDeb prix
Circuit Heleni
15
Circuit Heleni
15
Circuit Heleni
15
Rhapsodie hongroise 15
Budapest, Vienne
20
et Prague
VOYAGE
40
P
P
P
P
25-09-14
02-09-14
09-09-14
16-09-14
DP
09-09-14 1400
TARIF
Bases de données
33
690
680
680
790
Questions (5)
Nombre de départs pour chacun des
voyages dont le nom commence par ‘C’ ou
par ‘R’ ?
numVoyage
COUNT(*)
1
3
4
1
RESULTAT DE LA REQUETE
2013-2014
Bases de données
34
Questions (6)
Numéros des voyages coûtant toujours
le même prix (quelque soit la date de
départ) ?
SELECT numVoyage FROM Tarif
GROUP BY numVoyage
HAVING MAX(prix) = MIN(prix)
Variante
HAVING COUNT(DISTINCT prix) = 1
2013-2014
Bases de données
35
Questions (7)
Numéros des voyages coûtant toujours
moins de 500 € ?
SELECT numVoyage FROM Tarif
GROUP BY numVoyage
HAVING MAX(prix) < 500
2013-2014
Bases de données
36
Questions (8)
Numéros des voyages qui font étape
pendant plus de 4 jours dans une même
ville (par forcément de façon
consécutives) ?
SELECT DISTINCT numVoyage
FROM Etape
GROUP BY numVoyage, numVille
HAVING SUM(duree) > 4
2013-2014
Bases de données
37
Questions (8’)
Numéros des voyages qui font étape
pendant plus de 4 jours dans une même
ville (par forcément de façon
consécutives) ?
SELECT numVoyage, numVille
FROM Etape
GROUP BY numVoyage, numVille
HAVING SUM(duree) > 4
2013-2014
Bases de données
38
Questions (9)
Donner, pour chaque date de départ,
les numéros des voyages qui partent à
cette date
SELECT dateDeb, numVoyage
FROM Tarif
ORDER BY dateDeb
Utiliser GROUP BY et ORDER BY
à bon escient
2013-2014
Bases de données
39
Questions (10)
Donner, pour chaque date de départ, le
nombre de voyages qui partent à cette
date
SELECT dateDeb, COUNT(*)
FROM Tarif
GROUP BY dateDeb
2013-2014
Bases de données
40
Erreurs classiques
Utiliser dans la clause SELECT un
attribut qui n’est pas dans la clause
GROUP BY
Utiliser dans la clause HAVING un
attribut qui n’est pas dans la clause
GROUP BY
HAVING COUNT(*) = 0 et HAVING
COUNT(*) >= 1 n ’ont pas de sens
2013-2014
Bases de données
41
Analyse des requêtes
SELECT DISTINCT numVoyage, AVG(prix)
FROM Tarif
GROUP BY numVoyage
Ici le DISTINCT est inutile
2013-2014
Bases de données
42
Analyse des requêtes (2)
SELECT numVoyage, MIN(nomVoyage)
FROM Voyage
GROUP BY numVoyage
Ici MIN et GROUP BY sont inutiles
2013-2014
Bases de données
43
Analyse des requêtes (3)
SELECT DISTINCT typePension
FROM Voyage
GROUP BY typePension
Ici GROUP BY est inutile et donc
DISTINCT devient nécessaire
2013-2014
Bases de données
44
Analyse des requêtes (4)
SELECT COUNT(*) FROM Etape
GROUP BY numVille
HAVING numVille = 1
Ici, GROUP BY est une solution compliquée et
serait avantageusement remplacé par WHERE
SELECT COUNT(*) FROM Etape
WHERE numVille = 1
2013-2014
Bases de données
45

Documents pareils