Você está na página 1de 14

SQL DML SELECT requtes imbriques Lordre SELECT utilisation des REQUETES IMBRIQUEES ou sous-requtes

Une requte imbrique (sous-requte interne, en anglais : inner subquery) est une requte classique utilise pour constituer un jeu de rsultat qui va servir dans une requte principale, la requte appelante (requte externe, en anglais : outer query), en gnral comme lment de comparaison dans la clause WHERE, parfois comme lment constitutif de valeur dune colonne. Syntaxe gnrale :

SELECT . . .[, (requte_imbrique) AS alias_colonne] FROM . . . WHERE nom_colonne operateur (requte_imbrique) [ GROUP BY . . . ] [ HAVING nom_colonne operateur (requte_imbrique) ] [ ORDER BY . . . ] ; (requte_imbrique) est une requte identique toute autre requte (elle devra tre
entre parenthses, sans point-virgule la fin).

Fait appel Requte im brique Requte principale produit Rsultat produit Rsultat final
La requte imbrique doit cependant produire un ensemble de rsultats conforme loprateur de comparaison utilis dans la requte appelante :
VALEUR UNIQUE (1 ligne et 1 colonne) : oprateurs de comparaison simples =, <, >, <=,>=, <>, BETWEEN, ou bien utilisation dans la constitution de la valeur dune colonne LIGNES MULTIPLES, COLONNE UNIQUE (0 N lignes une seule colonne) : oprateurs IN, ALL, ANY Un JEU DE DONNEES QUELCONQUE (0 N LIGNES 1 N COLONNES) : oprateur EXISTS PATDEZ-2006- Lordre SELECT utilisation des REQUETES IMBRIQUEES Page 1/14

Utilis dans

SQL DML SELECT requtes imbriques


1- Deux formes de sous requtes : INDEPENDANTES (non corrles) et DEPENDANTES (corrles) A-INDEPENDANTES
Une requte indpendante peut tre lance seule, elle est totalement indpendante de la requte appelante. Lvaluation de la requte imbrique est dabord effectu une fois pour toutes et va servir (comme valeur unique, ou liste de valeurs) loprateur de comparaison de la requte appelante.

SELECT nummembre, nom , prenom FROM t_mem bre W HERE nummembre IN ( 1, 2, 4, 5 );


1 2

SELECT nummembre FROM t_inscrire

2
La requte imbrique est excute

(1, 2, 4, 5)

La requte principale sexcute et value la clause W HERE grce au rsultat retourn par la requte imbrique

B-DEPENDANTES, ou CORRELEES, ou LIEES


La requte imbrique va dpendre, cette fois, de valeurs de colonnes de la requte appelante, elle est lie la requte appelante, elle en est dpendante, corrle (en relation avec). La requte imbrique est alors effectu/value chaque ligne de la requte appelante.

CORRELATION

SELECT nom, prenom, titre, prix FROM t_artiste A INNER JOIN t_uvre O ON A.numartiste = O.numartiste W HERE prix < ( SELECT AVG(prix) 110 FROM t_uvre O2 W HERE O2.numartiste = A.numartiste );

(110)

1 2 3

La requte principale rcupre une ligne La requte imbrique sexcute et utilise dans sa clause W HERE une valeur de colonne de la requte principale La requte principale value la clause W HERE grce au rsultat retourn par la requte imbrique

PATDEZ-2006- Lordre SELECT utilisation des REQUETES IMBRIQUEES

Page 2/14

SQL DML SELECT requtes imbriques


2-Sous-requtes VALEUR UNIQUE
La VALEUR UNIQUE retourne par une requte imbrique va servir dlments de comparaison avec un oprateur de type : >, <, >=, <=, <> ou !=, BETWEEN. EN CAS DE RETOUR DUN ENSEMBLE DE RESULTAT MULTIPLE (PLUSIEURS LIGNES OU PLUSIEURS COLONNES, UNE ERREUR SE PRODUIT. Exemple :

Le titre des uvre d un artiste dont le nom est picasso


(1)_Retrouver le numro de lartiste dont le nom est picasso

SELECT numartiste FROM t_artiste WHERE LOWER(nom) = picasso ; SELECT titre FROM t_oeuvre WHERE numartiste = ( SELECT numartiste FROM t_artiste WHERE LOWER(nom) = picasso ) ;
Exemple :

Requte indpendante

(2)_Retrouver la liste des uvres dont le numro dartiste est celui trouv en (1) :

Les nom et prnom des membres qui se sont inscrits une activit avant de sinscrire lactivit Paris expo.
(1)_Retrouver le numro de lactivit Paris Expo.

SELECT numactivite FROM t_activite WHERE LOWER(intitule) = paris expo. ;

Requte indpendante

(2)_Retrouver la date dinscription cette activit POUR CHAQUE MEMBRE ( corrlation)

SELECT dateInscrire FROM t_inscrire WHERE numactivite = ( SELECT numactivite FROM t_activite WHERE LOWER(intitule) = paris expo. ) AND nummembre = <<MEMBRE DE LA TABLE APPELANTE>> ;

PATDEZ-2006- Lordre SELECT utilisation des REQUETES IMBRIQUEES

Page 3/14

SQL DML SELECT requtes imbriques


(3)_Retrouver la liste des membres qui ont une date dinscription antrieure la date dinscription trouve en (2)

SELECT DISTINCT nom, prenom FROM t_membre A INNER JOIN t_inscrire B ON A.nummembre = B.nummembre WHERE date_inscrire < CORRELATION ( SELECT dateInscrire FROM t_inscrire WHERE numactivite = ( SELECT numactivite FROM t_activite WHERE LOWER(intitule) = paris expo. ) AND nummembre = A.nummembre Requte ) corrle ;
Exemple :

Le titre des peintures (leur largeur et la largeur moyenne de toutes les peintures) dont la largeur est infrieure la moyenne
(1)_La largeur moyenne des peintures :

SELECT AVG(largeur) FROM t_peinture ;

Requte indpendante

(2)_Les oeuvres dont la largeur est infrieure au rsultat trouv en (1) ;(on affiche galement la largeur et sa moyenne autre utilisation de la requte imbrique valeur unique - afin de vrifier la bonne excution de la requte) :

SELECT titre, largeur, ( SELECT AVG(largeur) FROM t_peinture ) AS largeur_moyenne FROM t_oeuvre A INNER JOIN t_peinture B ON A.numoeuvre = B.numoeuvre WHERE largeur < ( SELECT AVG(largeur) FROM t_peinture ) ;

PATDEZ-2006- Lordre SELECT utilisation des REQUETES IMBRIQUEES

Page 4/14

SQL DML SELECT requtes imbriques


Exemple :

Le titre des peintures dont la largeur est suprieure la largeur moyenne de toutes les peintures
SELECT titre FROM t_oeuvre A INNER JOIN t_peinture B ON A.numoeuvre = B.numoeuvre WHERE largeur > (SELECT AVG(largeur) FROM t_peinture) ;
Exemple :

Le titre des peintures dont la largeur est gale la moyenne de toutes les peintures, plus ou moins 50%
SELECT titre FROM t_oeuvre A INNER JOIN t_peinture B ON A.numoeuvre = B.numoeuvre WHERE largeur BETWEEN ( SELECT AVG(largeur) * 0.50 FROM t_peinture ) AND ( SELECT AVG(largeur) * 1.5 FROM t_peinture ) ;
Exemple :

Le titre des peintures (leur largeur et la largeur moyenne des peintures pour chaque artiste) dont la largeur est suprieure la largeur moyenne des peintures du mme artiste
SELECT titre, largeur, (SELECT AVG(largeur) FROM t_oeuvre A2 INNER JOIN t_peinture B2 ON A2.numoeuvre = B2.numoeuvre WHERE A2.numartiste = A.numartiste ) CORRELATION AS moyenneParArtiste FROM t_oeuvre A INNER JOIN t_peinture B ON A.numoeuvre = B.numoeuvre WHERE largeur > ( SELECT AVG(largeur) CORRELATION FROM t_peinture WHERE numoeuvre IN
PATDEZ-2006- Lordre SELECT utilisation des REQUETES IMBRIQUEES Page 5/14

SQL DML SELECT requtes imbriques


( SELECT numoeuvre FROM t_uvre WHERE numartiste = A.numartiste ) ) ;

2-Sous-requtes LIGNES MULTIPLES, COLONNE UNIQUE


La COLONNE UNIQUE retourne par une requte imbrique va servir dlment de comparaison avec un oprateur traitant densemble de valeurs : IN et NOT IN, ALL, ANY . Oprateurs IN et NOT IN : Loprateur IN permet de vrifier quune valeur de colonne de la requte appelante existe dans la liste des valeurs retournes par la requte imbrique. Avec loprateur IN, AU MOINS UNE DES VALEURS de la sous requtes doit tre gale la valeur de la colonne externe . Exemple :

Le nom et le prnom des membres qui se sont inscrits au moins une fois une activit
(1)_les numros des membres qui se sont inscrits :

SELECT nummembre FROM t_inscrire ;


(1)_un membre peut sinscrire plusieurs fois, on peut optimiser le rsultat (en nayant quune seule fois un numro de membre suppression des doublons grce la clause DISTINCT) :

SELECT DISTINCT nummembre FROM t_inscrire ;


(2)_liste des membres dont le numro est parmi les numros de (1)

SELECT nom, prenom FROM membre WHERE nummembre IN (SELECT DISTINCT nummembre FROM t_inscrire ) ;
On aurait pu galement traiter la requte grce une jointure :

SELECT DISTINCT nom, prenom FROM t_membre A INNER JOIN t_inscrire B ON A.nummembre = B.nummembre ;
Exemple :

PATDEZ-2006- Lordre SELECT utilisation des REQUETES IMBRIQUEES

Page 6/14

SQL DML SELECT requtes imbriques Le nom et le prnom des membres qui NE se sont JAMAIS inscrits une activit
SELECT nom, prenom FROM t_membre WHERE nummembre NOT IN (SELECT DISTINCT nummembre FROM t_inscrire ) ;
ou bien

. . .WHERE NOT ( nummembre IN (SELECT DISTINCT nummembre FROM t_inscrire) );


Une jointure externe nous permet de rpondre galement cette question :

SELECT DISTINCT nom, prenom FROM t_membre A LEFT OUTER JOIN t_inscrire B ON A.nummembre = B.nummembre GROUP BY nom, prenom HAVING COUNT(B.nummembre) = 0 ;
Exemple :

Les nom et prnom des membres inscrits une activit consistant en une visite dexposition Paris
(1)_les numros des expositions ayant eu lieu Paris

SELECT numexpo FROM t_exposition WHERE LOWER(ville) = 'paris' ;


(2)_les numros des activits qui sont parmi la liste des numros de (1)

SELECT numactivite FROM t_visiter WHERE numexpo IN (SELECT numexpo FROM t_exposition WHERE LOWER(ville) = 'paris' ) ;
(3)_les numros des membres qui se sont inscrits une activit dont le numro est lun des numros de (2)

SELECT nummembre FROM t_inscrire WHERE numactivite IN (SELECT numactivite FROM t_visiter WHERE numexpo IN (SELECT numexpo FROM t_exposition
PATDEZ-2006- Lordre SELECT utilisation des REQUETES IMBRIQUEES Page 7/14

SQL DML SELECT requtes imbriques


WHERE LOWER(ville) = 'paris' ) ) ;
(4)_les membres dont le numro est lun des numros de (3)

SELECT nom, prenom FROM t_membre WHERE nummembre IN (SELECT nummembre FROM t_inscrire WHERE numactivite IN (SELECT numactivite FROM t_visiter WHERE numexpo IN (SELECT numexpo FROM t_exposition WHERE LOWER(ville) = 'paris' ) ) ) ;
Une jointure nous permet galement dobtenir ce rsultat :

SELECT DISTINCT nom, prenom FROM t_membre A INNER JOIN t_inscrire B ON A.nummembre = B.nummembre INNER JOIN t_visiter C ON B.numactivite = C.numactivite INNER JOIN t_exposition D ON C.numexpo = D.numexpo WHERE LOWER(D.ville) = 'paris' ;
Exemple :

le nombre, par anne de naissance, de membres qui se sont inscrits au moins une fois
(1)_les numros des membres qui se sont inscrits :

SELECT DISTINCT nummembre FROM t_inscrire ;


(2)_les membres dont le numro est parmi les numros de (1)

SELECT EXTRACT(YEAR FROM datenaissance), COUNT(*) FROM t_membre WHERE nummembre IN (SELECT DISTINCT nummembre FROM t_inscrire ) GROUP BY EXTRACT(YEAR FROM datenaissance);
ATTENTION : la jointure qui suit ne fournit pas le bon rsultat :

SELECT EXTRACT(YEAR FROM datenaissance), COUNT(*)


PATDEZ-2006- Lordre SELECT utilisation des REQUETES IMBRIQUEES Page 8/14

SQL DML SELECT requtes imbriques


FROM t_membre A INNER JOIN t_inscrire B ON A.nummembre = B.nummembre GROUP BY EXTRACT(YEAR FROM datenaissance);
En effet si un membre sest inscrit plusieurs fois, des activits diffrentes, il va tre compt plusieurs fois, moins dcrire :

SELECT EXTRACT(YEAR FROM datenaissance), COUNT(DISTINCT A.nummembre) FROM t_membre A INNER JOIN t_inscrire B ON A.nummembre = B.nummembre GROUP BY EXTRACT(YEAR FROM datenaissance);
Oprateur ALL : Loprateur ALL est associ un oprateur de comparaison et permet de contrler une valeur de colonne de la requte appelante par rapport toutes les valeurs retournes par la requte imbrique. Avec loprateur ALL, TOUTES les valeurs de la sous requtes doivent rpondre au critre de comparaison. Exemple :

Les membres qui sont plus jeunes que tous les membres qui se sont inscrits (= dont la date de naissance est suprieure toutes les dates de naissance des membres qui se sont inscrits)
SELECT * FROM t_membre WHERE datenaissance > ALL (SELECT datenaissance FROM t_membre A INNER JOIN t_inscrire B ON A.nummembre = B.nummembre ) ; > ALL (SELECT colonne . . .) est quivalent > (SELECT MAX( colonne ). . .) SELECT * FROM t_membre WHERE datenaissance > (SELECT MAX(datenaissance) FROM t_membre A INNER JOIN t_inscrire B ON A.nummembre = B.nummembre ) ;
Exemple :

Les membres qui sont plus gs que tous les membres qui se sont inscrits (= dont la date de naissance est infrieure toutes les dates de naissance des membres qui se sont inscrits)
SELECT * FROM t_membre
PATDEZ-2006- Lordre SELECT utilisation des REQUETES IMBRIQUEES Page 9/14

SQL DML SELECT requtes imbriques


WHERE datenaissance < ALL (SELECT datenaissance FROM t_membre A INNER JOIN t_inscrire B ON A.nummembre = B.nummembre ) ; < ALL (SELECT colonne . . .) est quivalent < (SELECT MIN( colonne ). . .) SELECT * FROM t_membre WHERE datenaissance < (SELECT MIN(datenaissance) FROM t_membre A INNER JOIN t_inscrire B ON A.nummembre = B.nummembre ) ;
Exemple :

Les membres qui ne sont pas ns la mme date que les membres qui se sont inscrits (= dont la date de naissance est diffrente de toutes les dates de naissance des membres qui se sont inscrits)
SELECT * FROM t_membre WHERE datenaissance <> ALL (SELECT datenaissance) FROM t_membre A INNER JOIN t_inscrire B ON A.nummembre = B.nummembre ) ; <> ALL (SELECT colonne . . .) est quivalent NOT IN (SELECT colonne . . .) SELECT * FROM t_membre WHERE datenaissance NOT IN (SELECT datenaissance) FROM t_membre A INNER JOIN t_inscrire B ON A.nummembre = B.nummembre ) ;
Oprateur ANY (ou SOME) : Loprateur ANY est associ un oprateur de comparaison et permet de contrler une valeur de colonne de la requte appelante par rapport toutes les valeurs retournes par la requte imbrique. Avec loprateur ANY, AU MOINS UNE des valeurs de la sous requte doit rpondre au critre de comparaison.

PATDEZ-2006- Lordre SELECT utilisation des REQUETES IMBRIQUEES

Page 10/14

SQL DML SELECT requtes imbriques


SELECT * FROM t_membre WHERE datenaissance < ANY (SELECT datenaissance FROM t_membre A INNER JOIN t_inscrire B ON A.nummembre = B.nummembre ) ; < ANY (SELECT colonne . . .) est quivalent < (SELECT MAX( colonne ). . .) SELECT * FROM t_membre WHERE datenaissance < (SELECT MAX(datenaissance) FROM t_membre A INNER JOIN t_inscrire B ON A.nummembre = B.nummembre ) ; SELECT * FROM t_membre WHERE datenaissance > ANY (SELECT datenaissance FROM t_membre A INNER JOIN t_inscrire B ON A.nummembre = B.nummembre ) ; > ANY (SELECT colonne . . .) est quivalent > (SELECT MIN( colonne ). . .) SELECT * FROM t_membre WHERE datenaissance > (SELECT MIN(datenaissance) FROM t_membre A INNER JOIN t_inscrire B ON A.nummembre = B.nummembre ) ; SELECT * FROM t_membre WHERE datenaissance = ANY (SELECT datenaissance FROM t_membre A INNER JOIN t_inscrire B ON A.nummembre = B.nummembre ) ; = ANY (SELECT colonne . . .) est quivalent IN (SELECT colonne . . .) SELECT * FROM t_membre WHERE datenaissance IN (SELECT DISINCT datenaissanc) FROM t_membre A INNER JOIN t_inscrire B ON A.nummembre = B.nummembre
PATDEZ-2006- Lordre SELECT utilisation des REQUETES IMBRIQUEES Page 11/14

SQL DML SELECT requtes imbriques


) ;

ALL

ANY ou SOME

suprieur toutes les valeurs de la sous- suprieur au moins une des valeurs de requte la sous-requte quivalent : quivalent :

>

> (SELECT MAX( colonne ). . .)


(suprieur la plus grande des valeurs de la liste) infrieur toutes les valeurs de la sousrequte quivalent :

> (SELECT MIN( colonne ). . .)


(suprieur la plus petite des valeurs de la liste) infrieur au moins une des valeurs de la sous-requte quivalent :

<

< (SELECT MIN( colonne ). . .)


(infrieur la plus petite des valeurs de la liste) diffrent de toutes les valeurs de la sousrequte

< (SELECT MAX( colonne ). . .)


(infrieur la plus grande des valeurs de la liste) diffrent dau moins une des valeurs de la sous-requte

<>

quivalent :

NOT IN (SELECT colonne. . .)


(nest pas parmi les valeurs de la liste) gal toutes les valeurs de la sous- gal au moins une des valeurs de la requte sous-requte

quivalent :

IN (SELECT colonne. . .)
(est parmi les valeurs de la liste)

PATDEZ-2006- Lordre SELECT utilisation des REQUETES IMBRIQUEES

Page 12/14

SQL DML SELECT requtes imbriques

3-Sous-requtes JEU DE DONNEES QUELCONQUE


Oprateur EXISTS : Loprateur EXISTS permet de contrler quune sous requte renvoie un rsultat non vide. Le rsultat de lvaluation est VRAI si le rsultat de la sous requte comporte au moins 1 ligne, (rsultat non vide) FAUX sinon. (rsultat vide, aucune ligne renvoye par la sous requte) Exemple :

la liste des artistes sil existe des membres dont lanniversaire est ft ce mois-ci
SELECT * FROM t_artiste WHERE EXISTS (SELECT * FROM t_membre WHERE EXTRACT(MONTH FROM dateNaissance) = EXTRACT(MONTH FROM CURRENT_DATE) ) ;
Exemple :

la liste des artistes sil existe certaines de leurs uvres qui ont t exposes
CORRELATION

SELECT * FROM t_artiste WHERE EXISTS (SELECT * FROM t_oeuvre A INNER JOIN t_exposer B ON A.numoeuvre = B.numoeuvre WHERE A.numartiste = t_artiste.numartiste ) ;
ATTENTION : si la sous requte comporte une fonction dagrgation, lapplication de loprateur EXISTS sera toujours vrifie : en effet, un COUNT(*) retourne forcment une valeur, qui peut tre 0 .

PATDEZ-2006- Lordre SELECT utilisation des REQUETES IMBRIQUEES

Page 13/14

SQL DML SELECT requtes imbriques


4-Evolution des normes SQL... suivre...
Les plus rcentes normes SQL modifient sensiblement le format des jeux de valeurs utiliss avec certains oprateurs dans lvaluation des requtes imbriques. Il devient possible de comparer non plus une seule valeur un ensemble de valeurs uniques, mais un jeu de valeurs dautres jeux de valeurs. Par exemple, loprateur IN peut tre utilis ainsi Exemple :

les membres qui sont aussi des artistes


SELECT * FROM t_membre WHERE (nom, prenom) IN ( SELECT nom, prenom FROM t_artiste ) ;
Vous pouvez tester en ajoutant un nouveau membre qui est aussi artiste :

INSERT INTO t_membre VALUES (30,null,'Pollock','Jackson','st james street' , 'london' , '1912/01/01');

PATDEZ-2006- Lordre SELECT utilisation des REQUETES IMBRIQUEES

Page 14/14

Você também pode gostar