Beruflich Dokumente
Kultur Dokumente
Une caractristique trs puissante de SQL est la possibilit dimbriquer une requte SQL
(SELECT) dans une autre. En effet, nous pouvons utiliser le rsultat dune requte pour formuler
une condition que lon utilise dans une autre requte dite requte principale.
Supposons quon veuille afficher les noms des employs qui sont mieux pays que ALLEN.
Pour rsoudre ce problme nous avons besoin de deux requtes ; la premire est dite sous-requte
et servira extraire le salaire de ALLEN. La deuxime est dite requte principale et servira
extraire les noms des employs en question en utilisant le rsultat de la sous-requte.
Il existe deux grandes familles de sous-requtes ; les sous-requtes corrles (synchronises, ou encore
dites dpendantes). Lexcution de ce type de requtes dpend de lexcution de la requte
principale do la corrlation. Ce type de requtes est complexe, il sera trait dans une section
ultrieure (dont worry). La deuxime famille est celle des sous-requtes non corrles, et dont
lexcution ne dpend pas de celle de la requte principale. La sous-requte est alors excute la
premire, son rsultat est utilis sparment pour lexcution de la requte principale.
WHERE
HAVING
FROM.
Dans le cas o elle est incluse dans les deux premires clauses, le rsultat de la sous-requte est
utilis comme tant un critre de recherche. Utilise dans la 3me clause, la sous-requte retourne
une relation (table virtuelle) partir de laquelle on pourrait extraire nos donnes. Lorsque la sousrequte est utilise dans les deux premires clauses, la requte principale a la forme suivante :
SELECT colonne(s) FROM table
WHERE exp OPERATEUR (SELECT colonne FROM table) ;
Il est vident quil doit y avoir une certaine cohrence entre lexpression exp quon a besoin de
comparer (expression de recherche, gnralement une colonne), loprateur de comparaison
OPERATEUR et le rsultat de la sous-requte. En dautres termes, la condition de la clause
WHERE doit tre construite logiquement (on ne peut pas comparer une colonne une liste de
valeurs si loprateur est =).
Une sous-requte simple retourne une relation une seule ligne ou plusieurs lignes. La
famille des sous-requtes simples peut tre alors divise en deux sous-familles, les sous-requtes
produisant une seule ligne et les sous-requtes produisant plusieurs lignes.
28
IN suivie dune liste de valeurs, la condition est vraie si notre exp est gale lune des
valeurs de la liste.
op ANY suivie dune liste de valeurs, la condition est vraie si la comparaison (en utilisant
loprateur op) est vraie pour nimporte quelle valeur de la liste.
op ALL suivie dune liste de valeurs, la condition est vraie si la comparaison (en utilisant
loprateur op) est vraie pour chaque valeur de la liste.
29
REQ 48
Afficher les employs les moins pays pour chaque dpartement ?
SELECT ENAME, SAL, DEPTNO FROM EMP
WHERE SAL IN (SELECT MIN(SAL) FROM EMP
GROUP BY DEPTNO) ;
ENAME
SAL DEPTNO
SMITH
800
20
JAMES
950
30
MILLER 1300
10
Maintenant, supposons que lemploy ADAMS qui travaille dans le dpartement 20 a le
salaire 1300 au lieu de 1100. ADAMS sera affich, car son salaire figure parmi les valeurs que
retourne la sous-requte. Cette solution prsente donc une faille, elle affichera tous les employs
dont le salaire est 1300, et non seulement les employs du dpartement 10 et dont le salaire est
1300 (de mme pour les valeurs 950 et 800). La bonne solution doit prendre en compte le
DEPTNO dans la comparaison.
REQ 49
Afficher les employs les moins pays pour chaque dpartement ?
SELECT ENAME, SAL, DEPTNO FROM EMP
WHERE (SAL,DEPTNO) IN (SELECT MIN(SAL),DEPTNO FROM EMP
GROUP BY DEPTNO) ;
Les oprateurs ANY et ALL peuvent tre utiliss avec tous les oprateurs de comparaison
classiques si on veut comparer une colonne plusieurs valeurs. La requte aura la forme
suivante :
SELECT colonne(s) FROM table
WHERE exp OPERATEUR_CLASSIC ANY/ALL (SELECT colonne
FROM table) ;
REQ 50
Afficher les employs qui sont mieux pays que tous les employs du dpartement 30 ?
SELECT ENAME, SAL FROM EMP
WHERE SAL > ALL (SELECT SAL FROM EMP
WHERE DEPTNO=30) ;
On peut aussi comparer une liste de colonnes (uplet de colonnes) au rsultat dune sousrequte ramenant plusieurs colonnes et plusieurs lignes. La requte aura la forme suivante :
SELECT colonne(s) FROM table
Le langage SQL version Oracle Document 1.1
Feedbacks anis.bach@isg.rnu.tn
30
= ANY IN
!= ALL NOT IN
=, !=,>,,<,
=, !=
[NOT] IN
(=, !=,>,,<,) ANY/ALL
[NOT] IN
= ANY ; !=ALL
REQ 51
Afficher les dpartements ayant une moyenne de salaires suprieure celle du dpartement
30 ?
SELECT DEPTNO, AVG(SAL) FROM EMP
GROUP BY DEPTNO
HAVING AVG(SAL)>(SELECT AVG(SAL) FROM EMP
WHERE DEPTNO=30) ;
REQ 52
Afficher le job ayant la plus grande moyenne de salaires ?
SELECT JOB, AVG(SAL) FROM EMP
GROUP BY JOB
HAVING AVG(SAL)=(SELECT MAX(AVG(SAL)) FROM EMP
GROUP BY JOB) ;
Il est noter quon ne peut pas trier une sous-requte. On ne peut utiliser la clause ORDER
BY qu la fin de la requte principale pour trier le rsultat final.
31
32
769
778
778
783
REQ 57
790
JOB
JON
ES
KE
RK
TT
G
D
BLA
CLA
SCO
KIN
FOR
DEPTNO
MANAGE
20
MANAGE
30
MANAGE
10
ANALYS
20
PRESID
ENT
ANALYS
T
10
R
R
R
T
20
33
R
Le langage SQL version Oracle Document 1.1
Feedbacks anis.bach@isg.rnu.tn
34
/B
B
b1
b2
D
A
a1
Remarquez que le produit cartsien de S et D est inclus dans la relation R. Ici, D contient les ai
qui sont en relation avec tous les bi de S.
D est alors le rsultat de la question suivante : Donnez les ai de R qui sont en relation avec
tous les bi de S ?
Mais on peut reformuler cette question dune autre manire : Donnez chaque ai de R tel quil
nexiste aucun bi de S qui ne soit pas en relation avec ai ?
Ainsi la traduction de la division dans le langage SQL se fait ainsi :
REQ 62
SELECT A FROM R R1
WHERE NOT EXISTS(SELECT B FROM S
WHERE NOT EXISTS(SELECT A, B FROM R R2
WHERE R2.A=R1.A AND R2.B=S.B);
Requte principale
Excution
Rsultat
de
lexcution
1re sous-requte
Excution
Rsultat
de
lexcution
2me sous-requte
Excution
Rsultat
de
lexcution
Requte principale
Excution
Rsultat
de
lexcution
35
1re sous-requte
Excution
Rsultat
de
lexcution
2me sous-requte
Excution
Rsultat
de
lexcution
b1 ne sera pas
retourne.
Celle-ci retourne
une ligne.
(a1,b1)
Celle-ci retourne
une ligne.
(a1,b2)
aucune ligne
b1 ne sera pas
retourne.
aucune ligne
aucune ligne
Requte principale
Excution
Rsultat
de
lexcution
36
1re sous-requte
Excution
Rsultat
de
lexcution
2me sous-requte
Excution
Rsultat
de
lexcution
a1
b1 ne sera pas
retourne.
Celle-ci retourne
une ligne.
(a2,b1)
Celle-ci ne
retourne aucune
ligne.
aucune ligne.
aucune ligne
Requte principale
Excution
Rsultat
de
lexcution
37
1re sous-requte
Excution
b2 sera alors
retourne
Rsultat
de
lexcution
2me sous-requte
Excution
Rsultat
de
lexcution
b2
On peut aussi calculer pour chaque ai, la diffrence entre (tous les bi de S) et (les bi avec qui il
est en relation). Si cette diffrence donne lensemble vide, cest que notre ai est en relation avec
tous les bi de S :
38
REQ 64
SELECT A FROM R R1
WHERE NOT EXISTS ( SELECT B FROM S
MINUS
SELECT B FROM R R2
WHERE R2.A=R1.A);
Ou encore :
REQ 66
SELECT A FROM R R1
WHERE (SELECT COUNT(DISTINCT B) FROM R R2
WHERE R2.A=R1.A)=(SELECT COUNT(B) FROM S);