2 Ils associent les rangées de 2 requêtes UNION [ALL] INTERSECT MINUS
les 2 ensembles doivent : –avoir le même nombre de colonnes –les colonnes doivent être de même type –la longueur des colonnes peut- être différente 3
4 Exemple : Afficher la liste des numéros de département situés à Montréal, ou qui contiennent au moins un employés qui touche une commission plus grande que $1000. SELECT id_departement FROM departement WHERE ville = Montréal UNION SELECT id_departement FROM employe WHERE commission >1000; Id_departement Id_departement 30 Id_departement
Lunion inclus donc dans un nouvel ensemble tous les éléments des deux SELECT. ALL = toutes les valeurs, même les doublons. Sans le All = valeurs distinctes UNION
6 Exemple Trouver la liste des numéro de département situés à Montréal et qui contiennent au moins un employé qui gagne un salaire de plus de $2,900. SELECT id_departement FROM employe WHERE salaire > 2900 INTERSECT SELECT id_departement FROM departement WHERE Ville = Montréal; Id_departement Id_departement 10 Id_departement 10
Lintersection met dans un nouvel ensemble tous les éléments communs aux deux SELECT INTERSECT 10
8 Afficher le numéro des départements qui ont au moins un employé qui gagne plus de $2900 et qui ne sont pas situés à Ottawa SELECT id_departement FROM employe WHERE salaire > 2900 MINUS SELECT id_departement FROM departement WHERE ville = Ottawa; Id_departement Id_departement 20 Id_departement 10
Le MINUS met dans un nouvel ensemble la soustraction des éléments du premier SELECT qui sont communs au deuxième SELECT MINUS MINUS Ensemble vide
10 Synonyme : requête imbriquée Il sagir dune requête comprise dans la clause WHERE dune autre requête Exemple : Afficher la liste des employés qui sont du même département que Rivest SELECT nom FROM employe WHERE id_departement = (SELECT id_departement FROM employe WHERE nom= rivest);
11 Limbrication peut continuer indéfiniment. Une sous-requête peut accéder à des tables différentes
Produire la liste des employés qui occupent le même type de poste que « Cabana » ou qui ont un salaire plus élevé que le sien: SELECT nom, poste, salaire FROM employe WHERE poste = ( SELECT poste FROM employe WHERE nom = 'cabana' ) OR salaire > ( SELECT salaire FROM employe WHERE nom= 'cabana' ); 12
Trouver la liste des employés de Calgary qui ont un salaire plus élevé que celui de Bergeron. Solution #1: SELECT imbriqués avec jonction de table SELECT nom, poste, salaire FROM employe, departement WHERE employe.id_departement = departement.id AND ville = 'Calgary AND salaire > ( SELECT salaire FROM employe WHERE nom = 'Bergeron' ); Solution #2: triple SELECT imbriqués SELECT nom, poste, salaire FROM employe WHERE id_departement IN ( SELECT id FROM departement WHERE ville = 'Calgary' ) AND salaire > ( SELECT salaire FROM employe WHERE nom = 'Bergeron' ); 13
Exemple : Produire la liste des plus anciens employés. SELECT nom FROM employe WHERE date_embauche = ( SELECT MIN(date_embauche) FROM employe ); 14
Les requêtes peuvent être classées selon le nombre de rangées qu'elles retournent. 1 - les requêtes qui retournent 0 ou 1 rangée. 2 - les requêtes qui retournent plus qu'une rangée. Certains opérateurs ( =,>,<,... ) exigent qu'une sous-requête soit du premier type. Exemple: Trouver la liste des employés qui ont le même salaire que Cabana. SELECT nom FROM employe WHERE salaire = ( SELECT // Comparaison de 1 ier type salaire FROM employe WHERE nom= 'Cabana' ); 15
On peut comparer des listes dexpressions. Exemple : Trouver la liste des employés qui ont le même salaire et qui sont du même département que Cabana: SELECT nom FROM employe WHERE ( salaire, id_departement) = ( SELECT salaire, id_departement FROM employe WHERE nom = 'Cabana' ); 16
Les 2 listes doivent avoir : le même nombre dexpressions les expressions doivent être de même type 17
Certains opérateurs acceptent des sous-requêtes qui retournent plusieurs rangées. Ces opérateurs sont: IN ANY ALL EXISTS 18
Compare une valeur à chaque valeur d'un ensemble. Signifie "est égal à n'importe quel membre d'un ensemble Exemple: Trouver la liste des employés qui travaillent dans un des départements situés à Québec. SELECT nom FROM employe WHERE id_departement IN (SELECT id FROM departement WHERE ville = 'Québec' ); 19
Compare une valeur à chaque valeur d'un ensemble. Doit être précédé de =,>, = ou <=. Exemple: X > ANY (Ensemble) retourne vrai si X est > que n'importe quelle valeur de l'ensemble. 20
Trouvez le nom des gestionnaires qui gagnent un salaire plus petit que lun des commis. SELECT nom FROM employe WHERE poste = gestion AND salaire < ANY ( SELECT salaire FROM employe WHERE poste =commis ); 21
=ANY est équivalent à IN X =ANY ( A, B, C ) est la même chose que X IN ( A, B, C ) 22
Compare une valeur à chaque valeur d'un ensemble Doit être précédé de =,>, =, ou <= Exemple: X > ALL ( ensemble) retourne vrai si X est > que toutes les valeurs de l'ensemble. 23
Trouvez la liste des employés qui ont été embauchés après les employés du département 20. SELECT nom FROM employe WHERE date_embuche > ALL ( SELECT date_embauche FROM employe WHERE id_departement= 20 ); 24
EXISTS ( Ensemble ) est vrai si l'ensemble contient au moins une valeur. NOT EXISTS ( Ensemble ) est vrai si l'ensemble est vide. 25
Trouver le nom des employés du département 30, si aucun employé du département 30 ne reçoit de commission. SELECT nom FROM employe WHERE id_departement= 30 AND NOT EXISTS ( SELECT * FROM employe WHERE id_departement= 30 AND commission IS NOT NULL ); 26
Il sagit dune sous-requête qui fait référence à des données de la requête principale. Exemple dune sous-requête non corrélative: Trouver les employés qui gagnent le salaire le plus petit du département 20. SELECT nom FROM employe WHERE salaire = (SELECT MIN(salaire) FROM employe WHERE id_departement = 20; 27 La sous requête est exécutée une fois seulement.
Exemple dune sous-requête corrélative: Exemple: Trouver les employés qui gagnent le plus petit salaire de leur département. SELECT nom FROM employe e1 WHERE salaire = ( SELECT MIN(e2.salaire) FROM employe e2 WHERE e2.id_departement = e1.id_departement ); 28 La sous requête est exécutée pour chaque rangée de la requête principale.
Trouvez le nom des employés qui font partie d'un département dans lequel aucun employé ne reçoit de commission. SELECT e1.nom FROM employe e1 WHERE NOT EXISTS ( SELECT * FROM employe e2 WHERE e2.id_departement = e1.id_departement AND e2.commission IS NOT NULL ); NOT EXISTS doit rien retourné pour être vraie. 29
Certain énoncés simples peuvent être complexes à résoudre. Exemple : quels sont les départements qui embauchent tous les employés de lusine? Étape 1: Tous les employés de lusine SELECT Usine.id FROM employe Usine; 30
Étape 2 : Est-ce que le département X embauche tous les employés: SELECT Oui FROM DUAL WHERE NOT EXISTS( (SELECT Usine.id FROM employe Usine) MINUS (SELECT EmpDept.id FROM employe EmpDept WHERE EmpDept.id = X) ); 31 X nest pas une valeur valide.
Dernière étape : Il faut généraliser pour tous les départements (remplacer le X par un générateur) : SELECT e1.id_departement FROM employe e1 WHERE NOT EXISTS( (SELECT Usine.id FROM employe Usine) MINUS (SELECT EmpDept.id FROM employe EmpDept WHERE EmpDept.id = e1.id) ); 32