Nous utiliserons pour ce cours les données de A.2.
Si on souhaite connaître les numéros des modules pré-requis pour s’inscrire dans le module ’PL/SQL Oracle’, il nous faut tout d’abord le numéro de ce module :
SELECT numMod FROM MODULE WHERE nomMod = 'PL/SQL Oracle' numMod 6
Ensuite, cherchons les numéros des modules pré-requis pour s’inscrire dans le module numéro 6,
SELECT numModPrereq FROM PREREQUIS WHERE numMod = 6; numModPrereq 1 5
Et pour finir, allons récupérer les noms de ces modules,
SELECT nomMod FROM MODULE WHERE numMod IN (1, 5); nomMod Oracle Merise
Vous êtes probablement tous en train de vous demander s’il n’existe pas une méthode plus simple et plus rapide, et surtout une façon d’automatiser ce que nous venons de faire. Il existe un moyen de sélectionner des données dans plusieurs tables simultanément. Pour traiter la question ci-dessus il suffisait de saisir :
SELECT m2.nomMod FROM MODULE m1, MODULE m2, PREREQUIS p WHERE m1.numMod = p.numMod AND m2.numMod = p.numModprereq AND m1.nomMod = 'PL/SQL Oracle'; nomMod Oracle Merise
Le but de ce chapitre est d’expliciter ce type de commande.
L’instruction SELECT ... FROM ... peut s’étendre de la façon suivante :
SELECT <listecolonnes> FROM <listetables>
L’exemple ci-dessous vous montre le résultat d’une telle commande.
SELECT * FROM PROPOSER, PRODUIT; numfou numprod prix numprod nomprod 2 3 1 1 Bocal de cornichons 2 2 2 1 Bocal de cornichons 2 1 3 1 Bocal de cornichons 1 1 2 1 Bocal de cornichons 2 3 1 2 Tube de dentifrice 2 2 2 2 Tube de dentifrice 2 1 3 2 Tube de dentifrice 1 1 2 2 Tube de dentifrice 2 3 1 3 Flacon de lotion anti-escarres 2 2 2 3 Flacon de lotion anti-escarres 2 1 3 3 Flacon de lotion anti-escarres 1 1 2 3 Flacon de lotion anti-escarres 2 3 1 4 Déodorant fraîcheur 96 heures 2 2 2 4 Déodorant fraîcheur 96 heures 2 1 3 4 Déodorant fraîcheur 96 heures 1 1 2 4 Déodorant fraîcheur 96 heures
Placer une liste de tables dans le FROM revient à former toutes les combinaisons de lignes possibles. Cependant, cela a relativement peu de sens.
Il serait plus intéressant, dans le cas présent, de ne voir s’afficher que des lignes dont les numéros de produits concordent. Pour ce faire, il suffit d’utiliser WHERE. Par exemple,
SELECT * FROM PROPOSER, PRODUIT WHERE PROPOSER.numprod = PRODUIT.numprod; numfou numprod prix numprod nomprod 1 1 2 1 Bocal de cornichons 2 1 3 1 Bocal de cornichons 2 2 2 2 Tube de dentifrice 2 3 1 3 Flacon de lotion anti-escarres
Nous avons mis en correspondance des lignes de la table proposer avec des lignes de la table produit en utilisant le fait que numprod est une clé étrangère dans proposer. Comme la colonne numprod apparaît deux fois dans la requête, il est nécessaire de la préfixer par le nom de la table de sorte que chaque colonne puisse être désignée de façon non ambiguë. Si on veut mettre face à face les noms des produits et les noms des fournisseurs, il suffit de saisir la requête
SELECT nomfou, nomprod FROM PRODUIT, FOURNISSEUR, PROPOSER WHERE PRODUIT.numProd = PROPOSER.numProd AND FOURNISSEUR.numFou = PROPOSER.numFou; nomfou nomprod Bocaux Gérard Bocal de cornichons Paramédical Gisèle Bocal de cornichons Paramédical Gisèle Tube de dentifrice Paramédical Gisèle Flacon de lotion anti-escarres
En utilisant la syntaxe suivante, il est possible de renommer les tables,
FROM <table_1> <table_1_renommee>, ..., <table_n> <table_n_renommee>
Reformulons la requête ci-dessus,
SELECT nomfou, nomprod FROM PRODUIT p, FOURNISSEUR f, PROPOSER pr WHERE p.numProd = pr.numProd AND f.numFou = pr.numFou; nomfou nomprod Bocaux Gérard Bocal de cornichons Paramédical Gisèle Bocal de cornichons Paramédical Gisèle Tube de dentifrice Paramédical Gisèle Flacon de lotion anti-escarres
Le renommage permet entre autres de faire des jointures réflexives, c’est à dire entre une table et elle même. Par exemple, en reprenant la table intervalle,
SELECT * FROM INTERVALLE; borneInf borneSup 0 30 2 3 2 56 5 10 7 32 8 27 12 3 12 30 21 8 34 26
La commande ci-dessous affiche tous les couples d’intervalles ayant une borne en commun,
SELECT * FROM INTERVALLE i, INTERVALLE j WHERE (i.borneInf = j.borneInf AND i.borneSup < j.borneSup) OR (i.borneInf < j.borneInf AND i.borneSup = j.borneSup); borneInf borneSup borneInf borneSup 0 30 12 30 2 3 2 56 2 3 12 3 12 3 12 30