Bon, on vient de se taper un bon gros morceau là, avec les jointures. Sachez que c'est ce qui est le plus utilisé au niveau des bases de données. Ce n'est pas le plus compliqué à faire, mais il faut le connaître. La prochaine étape est une autre méthode permettant de "joindre" les résultats d'une requête à une des conditions d'une requête.
"J'ai rien compris à votre phrase! Vous pouvez expliquer un peu ou au moins donner quelques exemples?"
Je sais, ce n'est pas la partie la plus simple des bases de données. A vrai dire c'est même le plus dure à appréhender, mais je vais quand même essayer de vous le faire comprendre.
Alors, ce qu'il faut comprendre donc, c'est que le résultat d'une requête SFW peut être utilisé dans la clause from ou dans la clause where d'une autre requête. Par exemple, nous avons plusieurs groupe de TP. Et bien on pourra faire une requête du genre "quels sont les élèves du 1er groupe qui ont plus que tous les élèves du deuxième groupe" ou sans jointure demander "nom de tous les élèves qui ont eu des notes en PHP". Pratique non?
Il existe plusieurs opérateurs permettant de faire des compositions de requêtes:
Il permet de spécifier sur un attribut si celui-ci est présenté dans la liste des valeurs retournée par une requête. Du coup cette sous-requête ne devra évidemment renvoyer une table à une seule colonne, ou liste de valeurs!
Voilà la syntaxe: select ... from R where X in (select S from Y where ...)
Il est évidemment possible de sélectionner l'inverse avec not in.
mysql> # liste des personnes qui travaillent
mysql> select nom,prenom from personnes where nss in (select nss from travaillent);
mysql> # liste des personnes qui ne travaillent pas
mysql> select nom,prenom from personnes where nss not in (select nss from travaillent);
L'opérateur EXISTS
Il permet de spécifier si une sous-requête incluse dans une condition renvoie au moins un résultat par rapport au reste de la requête.
Voilà la syntaxe: select ... from R where exists (select * from Y where C) Ici la condition C doit comporter au moins un attribut de R.
Il est évidemment possible de sélectionner l'inverse avec not exists.
mysql> # liste des personnes qui travaillent
mysql> select nom,prenom from personnes where exists (select * from travaillent where travaillent.nss=personnes.nss);
mysql> # liste des personnes qui ne travaillent pas
mysql> select nom,prenom from personnes where not exists (select * from travaillent where travaillent.nss=personnes.nss);
"Mais du coup à quoi ça sert? Car on pourrait très bien faire une jointure au lieu d'utiliser exists!"
Dans cet exemple oui, mais prenons un exemple plus compliqué.
mysql> # liste des nss qui travaillent dans le département de math et dans celui d'info
mysql> select nss from travaillent where dep='Maths' and exists (select * from travaillent t2 where travaillent.nss=t2.nss and t2.dep='Info');
Le quantificateur existentiel any
Il généralise in, et permet d'exprimer une requête du type "il existe...".
Voilà la syntaxe: select ... from R where X bop any (select S from Y where ...) bop veut dire binary operator (=, >, <, >=, <=).
Soit t ∈ R. t est sélectionnée si ∃ t' ∈ S tq t[X] bop t'[Y].
Le quantificateur universel all
Il suit le même concept que in, et permet d'exprimer une requête du type "pour tous les...".
Voilà la syntaxe: select ... from R where X bop all(select S from Y where ...) bop veut dire binary operator (=, >, <, >=, <=).
Soit t ∈ R. t est sélectionnée si ∀ t' ∈ S tq t[X] bop t'[Y].
Quelques exemples concrets:
eleves
cours
affectation
in et exists
mysql> # liste des étudiants qui ont une note en perl
mysql> select id_e from aff where id_c in (select id_c from cours where nom_c='perl');
mysql> select id_e from aff where exists (select cours.id_c from cours where cours.id_c=prof.id_c and nom_c='perl');
any et all
mysql> liste des étudiants de la classe 5 qui ont plus qu'au moins 1 étudiant de la classe 3
mysql> select id_e from aff where id_c=5 and note > ANY (select note from aff where id_c=3);
mysql> liste des étudiants de la classe 5 qui ont plus que tous les étudiants de la classe 3
mysql> select id_e from aff where id_c=5 and note > ALL (select note from aff where id_c=3);
Vous venez de faire la partie la plus compliquée du cours! bravo à vous! J'espère que vous avez bien tout saisi, sinon n'hésitez pas à revenir sur cette page, ou sur les exercices que l'on fera plus tard!