Vous êtes sur la page 1sur 34

BASES DE DONNEES AVANCEES

Lotfi NAJDI
Année Universitaire 2020 / 2021
Licence Professionnelle Génie Informatique
Faculté Polydisciplinaire de Taroudant
Qu'est-ce qu'une Sous-Interrogation ?

 Une sous-interrogation est une commande SELECT imbriquée dans une


clause d'un autre ordre SQL.

 La sous-interrogation (requête interne ou inner query) est exécutée avant la requête


principale(outer query) .

 Le résultat de la sous-interrogation est utilisé par la requête principale (requête


externe).

Requête SELECT . . .
principale FROM . . .
WHERE . . .
(SELECT . . . Sous-interrogation
FROM . . .
WHERE . . .)
Utilisation d'une Sous-Interrogation pour résoudre un problème
donné
"Qui a un salaire supérieur à celui de Abel ?"

Requête principale

"Quels employés ont un salaire supérieur à celui de Jones ?"

Sous-interrogation

?
"Quel est le salaire de Abel?"
Sous-interrogation

SELECT First_name,last_name, salary


FROM employees
WHERE salary > 11000
(SELECT salary
FROM employees

WHERE last_name = 'Abel' );


Règles d'utilisation des sous-interrogations

 Utilisez des parenthèses pour mettre en lumière les sous requêtes

 Placer la sous-requête sur le côté droit de l'opérateur de comparaison.

 Indenter votre code, afin qu’il soit lisible .


Sous-Interrogation retournant une seule ligne

 Renvoient une seule ligne

 La ligne retournée va servir comme élément de comparaison.

 Les opérateurs à utiliser pour la comparaison sont :

 =, >, <, >=, <=,

 <> ou !=,

 BETWEEN,

 LIKE.
Sous-Interrogation retournant une seule ligne
SELECT last_name, job_id, salary
FROM employees
WHERE job_id =
( SELECT job_id SA_REP
FROM employees
WHERE last_name = 'Taylor' and first_name = 'Jonathon')
AND salary >
(SELECT salary 8600
FROM employees
WHERE last_name = 'Taylor' and first_name = 'Jonathon') ;
Utilisation des fonctions de groupement à l’intérieur des sous
interrogations

SELECT last_name, job_id, salary


FROM employees
WHERE salary = 2100
(SELECT MIN(salary)
FROM employees);
Utilisation des fonctions de groupement à l’intérieur des sous
interrogations

SELECT First_name,last_name, job_id, salary


FROM employees
WHERE salary > 6461,83
(SELECT avg(salary) FROM employees);
Utilisation de la Clause HAVING avec les sous interrogations

SELECT department_id, MIN(salary)


FROM employees
GROUP BY department_id
HAVING MIN(salary) > 8300
(SELECT MIN(salary)
FROM employees
WHERE department_id = 110);

 Le serveur Oracle exécute dans un premier temps la sous-requête.

 Le serveur Oracle renvoie les résultats dans la clause HAVING de la requête principale.
Utilisation de la Clause HAVING avec les sous interrogations

SELECT department_id, MIN(salary)


FROM employees
GROUP BY department_id
HAVING MIN(salary) > 8300
(SELECT MIN(salary)
FROM employees
WHERE department_id = 110);
Qu'est-ce qui ne va pas dans cette requête ?
SELECT employee_id, last_name
FROM employees
WHERE salary =
(SELECT MIN(salary)
FROM employees
GROUP BY department_id);
Qu’est-ce quine va pas dans cette requête ?
SELECT employee_id, last_name
FROM employees
WHERE salary =
( SELECT MIN(salary)
FROM employees
GROUP BY department_id );
Requête imbriquée retournant plusieurs lignes

 Retourne plus d'une ligne

 Utilise les opérateurs de comparaison à plusieurs lignes

Opérateur Description

IN vérifier si une valeur est égale à une des valeurs comprise dans
la liste retournée par la sous requête.

ANY vérifier si une valeur satisfait une condition, pour au moins


une des valeurs de la sous-requête.
Doit être précédé par =, !=, >, <, <=, >=.

ALL vérifier si une valeur satisfait une condition, pour tous les
résultats retourné par une sous-requête.
Doit être également précédé par =, !=, >, <, <=, >=.
Requête imbriquée retournant plusieurs lignes

Les opérateurs AYN et ALL sont utilisés avec une clause "WHERE" ou "HAVING".

 L'opérateur ANY Renvoie TRUE si l'une des valeurs retournées par la sous-requête (au

moins une ) , remplit la condition.

 L'opérateur ALL renvoie TRUE si la condition est satisfaite par toutes les valeurs

retournées par la sous-requête.


Utilisation de l’opérateur IN avec les sous interrogations multi
lignes
SELECT employee_id, last_name, job_id, salary
FROM employees
WHERE salary IN 4200 4800 6000 9000
( SELECT salary
FROM employees
WHERE job_id = 'IT_PROG')

AND job_id <> 'IT_PROG';


Utilisation de l’opérateur ANY avec les sous interrogations multi lignes

SELECT employee_id, last_name, job_title, salary


FROM employees
JOIN jobs USING(job_id)
WHERE salary > ANY 4200 4800 6000 9000
( SELECT salary
FROM employees
WHERE job_id = 'IT_PROG')
AND job_id <> 'IT_PROG';

57 Lignes
Utilisation de l’opérateur ALL avec les sous interrogations multi lignes

SELECT employee_id, last_name, job_title, salary


FROM employees
JOIN jobs USING(job_id)
WHERE salary > ALL 4200 4800 6000 9000
( SELECT salary
FROM employees
WHERE job_id = 'IT_PROG')
AND job_id <> 'IT_PROG';

23 Lignes
Règles d'utilisation des sous-interrogations (suite)

 Utiliser l’opérateur qui convient en fonction de la sous-requête Opérateur mono-ligne

avec un requête mono-ligne(opérateur multi-ligne avec une requête multi-lignes)

 Faire correspondre le nombre de membres des tuples présents de chaque côté du

critère de recherche.
Valeurs Null et sous interrogations
IN est équivalent à =ANY  NULL ne pose pas de problème

SELECT emp.first_name , emp.last_name , emp.salary


FROM employees emp
WHERE emp.employee_id IN (
SELECT distinct manger.manager_id
FROM employees manger );
Valeurs Null et sous interrogations
NOT IN est équivalent à <>ALL  NULL pose problème

SELECT emp.first_name , emp.last_name , emp.salary


FROM employees emp
WHERE emp.employee_id NOT IN (
SELECT distinct manger.manager_id
FROM employees manger );
Sous-requête Imbriquée vs Corrélée

On distingue deux types de sous-requêtes :

• Sous-requête imbriquée : pas de lien explicite entre la requête interne, qui est exécutée 1 seule

fois.

• Sous-requête corrélée ou synchronisée : la requête interne fait référence à la requête externe et

est exécutée pour chaque ligne de la cette dernière


Utilisation de Sous-Interrogations Synchronisées
Recherchez tous les employés qui gagnent plus que le salaire moyen de leur département.

Chaque fois qu’une


SELECT emp1.employee_id , emp1.salary, emp1.department_id ligne de la requête
externe est traitée,
FROM employees emp1 la requête interne
est exécutée.
WHERE salary > ( SELECT AVG(emp2.salary)
FROM employees emp2
WHERE emp2.department_id = emp1.department_id ) ;
Utilisation de l'Opérateur EXISTS

Principe :

 EXISTS permet de vérifier si une sous-requête retourne un résultat ou non.

 En d’autres termes, évaluer la présence ou non de lignes lors de l’utilisation d’une


sous-requête.

 La requête externe s’exécutera uniquement si la requête interne retourne au moins un


résultat.

Fonctionnement :

 Dès qu’une ligne est trouvée par la sous-interrogation , la recherche dans la requête
interne est interrompue et la condition est évaluée comme TRUE.

 Si aucune ligne n’est trouvée par la sous-interrogation, la condition est fausse (FALSE). *
EXISTS / NOT EXISTS

EXISTS

NOT EXISTS
EXISTS / NOT EXISTS

EXISTS Condition (oracle.com)


Utilisation de l'Opérateur EXISTS

Recherchez tous les départements qui comprennent des employés.

SELECT department_name, department_id FROM departments d


WHERE NOT EXISTS (SELECT * FROM employees e
WHERE d.department_id = e.department_id);
Utilisation de l'Opérateur EXISTS

Recherchez tous les employées qui sont des managers.


Notez que la requête interne n'a pas besoin de
SELECT * retourner une valeur spécifique, une constante
peut être sélectionnés.
FROM employees mgr
WHERE EXISTS ( select '1' from employees empl
WHERE empl.manager_id = mgr.employee_id );
Utilisation de l'Opérateur NOT EXISTS

Recherchez tous les départements qui ne comprennent pas d'employés.

SELECT dep.department_id , dep.department_name


FROM departments dep
WHERE dep.department_id NOT IN (SELECT department_id FROM employees emp );
Utilisation de l‘opérateur NOT EXISTS

Recherchez tous les départements qui ne comprennent pas d'employés.

SELECT dep.department_id , dep.department_name


FROM departments dep
WHERE NOT EXISTS (SELECT '1' FROM employees emp
WHERE dep.department_id = emp.department_id);
Utilisation de l'Opérateur EXISTS

 les opérateurs EXISTS et NOT EXISTS offrent de très bonnes performances par rapport aux

opérateurs IN et NOT IN lorsque les résultats de la sous-requête sont très importants..

 La commande EXISTS vérifie si la sous-requête retourne un résultat ou non, tandis que IN

vérifie toutes les valeurs de la colonne correspondante au niveau de sous-requête.

 Dans le cas de IN, le moteur SQL analyse tous les enregistrements récupérés dans la

requête interne. Tandis que, pour EXISTS, le moteur SQL va arrêter le processus de

balayage dès qu'il trouve une correspondance.


Utilisation de Sous-Interrogations avec plusieurs colonnes

Employés dont le salaire et la commission sont identiques à ceux d'un employé du


département 30.

SELECT First_name, last_name, salary , COMMISSION_PCT


FROM employees
WHERE (salary, NVL(COMMISSION_PCT, -1)) IN
(SELECT salary, NVL(COMMISSION_PCT, -1)
FROM employees
WHERE DEPARTMENT_ID = 80);
Utilisation d'une Sous-Interrogation dans la Clause FROM

SELECT first_name,salary,round(dep_salavg,2),emp.department_id
FROM employees emp,( SELECT department_id, AVG(salary) dep_salavg
FROM employees
GROUP BY department_id ) dep
WHERE emp.department_id = dep.department_id;

Vous aimerez peut-être aussi