398 Chapitre 10. Récapitulatif SQL En résumé, le NULL est une source de problèmes : dans la mesure du possible il faut l’éviter au moment où on définit la table en spécifiant la contrainte NOT NULL ou en imposant une valeur par défaut. Si la valeur par défaut n’est pas fixée à la création de la table, on peut en donner une au moment de l’exécution de la requête avec la fonction IFNULL() qui remplace une valeur NULL par son deuxième argument. mysql> SELECT IFNULL(annee_naissance, ’Pas de date de naissance !?’) -> FROM Artiste; + + | IFNULL(annee_naissance, ’Pas de date de naissance !?’) | + + | 1930 | | 1930 | | 1925 | | Pas de date de naissance !? | | 1910 | + + 10.1.7 Clauses spécifiques à MySQL La clause LIMIT peut être placée à la fin de toute requête SQL, et indique le nombre maximal de lignes dans le résultat. mysql> SELECT * -> FROM Film -> LIMIT 3; + + + + + | titre | annee | id_realisateur | genre | + + + + + | Impitoyable | 1992 | 20 | Western | | Van Gogh | 1990 | 29 | Drame | | Kagemusha | 1980 | 68 | Drame | + + + + + Si on utilise deux chiffres comme, par exemple, LIMIT 1,3, le premier indique le numéro de la ligne à partir de laquelle la limite s’applique, les lignes étant numérotées à partir de 0. mysql> SELECT * -> FROM Film -> LIMIT 1,3; + + + + + | titre | annee | id_realisateur | genre | + + + + + | Van Gogh | 1990 | 29 | Drame | | Kagemusha | 1980 | 68 | Drame | | Les pleins pouvoirs | 1997 | 20 | Policier | + + + + + 10.2 Jointures 399 Au lieu d’afficher à l’écran, on peut placer le résultat d’un ordre SELECT dans un fichier : SELECT * INTO OUTFILE ’./svfilm.txt’ FROM Film Il faut disposer du privilège file pour utiliser INTO OUTFILE. On obtient alors tous les droits d’accès du serveur mysqld. Par défaut, le fichier est créé dans le répertoire contenant les bases de données. On peut indiquer explicitement le chemin d’accès, à condition que le programme client mysql ait le droit d’écriture. Les lignes de la table sont écrites en séparant chaque valeur par une tabulation, ce qui permet de recharger le fichier par la suite avec la commande LOAD DATA (voir la section présentant cette commande, page 29). On peut indiquer, après le nom du fichier, les options de séparation des lignes et des attributs, avec une syntaxe identique à celle utilisée pour LOAD DATA : voir annexe B. 10.2 JOINTURES La jointure est une des opérations les plus utiles (et l’une des plus courantes) puisqu’elle permet d’exprimer des requêtes portant sur des données réparties dans plusieurs tables. La syntaxe pour exprimer des jointures avec SQL est une extension directe de celle étudiée précédemment dans le cas des sélections simples : on donne la liste des tables concernées dans la clause FROM, et on exprime les critères de rapprochement entre ces tables dans la clause WHERE. 10.2.1 Interprétation d’une jointure Prenons l’exemple de la requête donnant le titre des films avec le nom et le prénom de leur metteur en scène. mysql> SELECT titre, prenom, nom -> FROM Film, Artiste -> WHERE id_realisateur = id; + + + + | titre | prenom | nom | + + + + | Impitoyable | Clint | Eastwood | | Les pleins pouvoirs | Clint | Eastwood | | Van Gogh | Maurice | Pialat | | Kagemusha | Akira | Kurosawa | + + + + Pour bien comprendre ce que signifie une jointure, ce qui est parfois difficile quand on commence à utiliser SQL, on peut généraliser l’interprétation donnée 400 Chapitre 10. Récapitulatif SQL dans le cas d’une seule table. La clause FROM, dans les deux cas, définit un « espace de recherche» qui, quand il y a une seule table, correspond à toutes les lignes de celle-ci. Quand il y a deux tables, cet espace de recherche est constitué de toutes les combinaisons possibles des lignes des deux tables. La figure 10.2 montre toutes ces combinaisons sous la forme d’une table, compre- nant 4 × 5 = 20 lignes construites à partir des 4 lignes de Film et des cinq lignes de Artiste. Appelons-la FilmXArtiste : elle peut être obtenue avec la requête. SELECT titre, prenom, nom FROM Film, Artiste Dans cette table, beaucoup de lignes ne nous intéressent pas, comme celles qui associent Pialat et Impitoyable,ouVan Gogh et Kurosawa. En fait on ne veut garder que celles pour lesquelles l’attribut id_realisateur est égal à l’attribut id,soit4 lignes. titre annee id_real. genre id nom prenom annee_naiss. Impitoyable 1992 20 Western 20 Eastwood Clint 1930 Impitoyable 1992 20 Western 21 Hackman Gene 1930 Impitoyable 1992 20 Western 29 Pialat Maurice 1925 Impitoyable 1992 20 Western 30 Dutronc Jacques Impitoyable 1992 20 Western 68 Kurosawa Akira 1910 Van Gogh 1990 29 Drame 20 Eastwood Clint 1930 Van Gogh 1990 29 Drame 21 Hackman Gene 1930 Van Gogh 1990 29 Drame 29 Pialat Maurice 1925 Van Gogh 1990 29 Drame 30 Dutronc Jacques Van Gogh 1990 29 Drame 68 Kurosawa Akira 1910 Kagemusha 1980 68 Drame 20 Eastwood Clint 1930 Kagemusha 1980 68 Drame 21 Hackman Gene 1930 Kagemusha 1980 68 Drame 29 Pialat Maurice 1925 Kagemusha 1980 68 Drame 30 Dutronc Jacques Kagemusha 1980 68 Drame 68 Kurosawa Akira 1910 Les pleins pouvoirs 1997 20 Policier 20 Eastwood Clint 1930 Les pleins pouvoirs 1997 20 Policier 21 Hackman Gene 1930 Les pleins pouvoirs 1997 20 Policier 29 Pialat Maurice 1925 Les pleins pouvoirs 1997 20 Policier 30 Dutronc Jacques Les pleins pouvoirs 1997 20 Policier 68 Kurosawa Akira 1910 Figure 10.2 —TableFilmXArtiste, définie par la clause FROM Film, Artiste. La jointure est simplement une sélection sur cette table FilmXArtiste, que l’on pourrait exprimer de la manière suivante si cette table existait. SELECT titre, prenom, nom FROM FilmXArtiste WHERE id_realisateur = id 10.2 Jointures 401 L’interprétation d’une jointure est donc une généralisation de l’interprétation d’un ordre SQL portant sur une seule table. On parcourt toutes les lignes définies par la clause FROM, et on leur applique la condition exprimée dans le WHERE. Finalement, on ne garde que les attributs spécifiés dans la clause SELECT. C’est vrai quel que soit le nombre de tables utilisées dans le FROM. Une remarque importante pour finir : la jointure est une opération qui consiste à reconstituer une association entre entités (voir chapitre 4), dans notre exemple l’association entre un film et son metteur en scène. Comme nous avons vu que cette association était représentée dans un schéma relationnel par le mécanisme de clés primaires et clés étrangères, la plupart des jointures s’expriment par une égalité entre la clé primaire d’une table et la clé étrangère correspondante dans l’autre table. C’est le cas dans l’exemple ci-dessus, où id_realisateur est la clé étrangère, dans Film, correspondant à la clé primaire id dans Artiste. 10.2.2 Gestion des ambiguïtés Dans l’exemple précédent, il n’y a pas d’ambiguïté sur les noms des attributs : titre et id_realisateur viennent de la table Film, tandis que nom, prenom et id viennent de la table Artiste. Il peut arriver (il arrive de fait fréquemment) qu’un même nom d’attribut soit partagé par plusieurs tables impliquées dans une jointure. Dans ce cas, on résout l’ambiguïté en préfixant l’attribut par le nom de sa table. Exemple : afficher, pour chaque film, les rôles du film. mysql> SELECT Film.titre, nom_role -> FROM Film, Role -> WHERE Film.titre = Role.titre; + + + | titre | nom_role | + + + | Impitoyable | William Munny | | Impitoyable | Little Bill Dagget | | Van Gogh | Van Gogh | | Les pleins pouvoirs | Le pr´esident | + + + Il n’y a pas ici de problème pour nom_role qui désigne sans ambiguïté possible un attribut de la table Role. Si, en revanche, on ne préfixe pas titre par la table dont il provient, MySQL ne sait pas évaluer la requête. mysql> SELECT titre, nom_role -> FROM Film, Role -> WHERE titre = titre; ERROR 1052: Column: ’titre’ in field list is ambiguous Comme il peut être fastidieux de répéter intégralement le nom d’une table, on peut lui associer un synonyme et utiliser ce synonyme en tant que préfixe. La requête précédente devient par exemple : 402 Chapitre 10. Récapitulatif SQL SELECT f.titre, nom_role FROM Film AS f, Role AS r WHERE f.titre = r.titre Pour obtenir le nom de l’acteur qui a joué le rôle, il faut effectuer une jointure supplémentaire avec la table Artiste. mysql> SELECT f.titre, prenom, nom, nom_role -> FROM Film AS f, Role AS r, Artiste -> WHERE f.titre = r.titre -> AND id_acteur = id; + + + + + | titre | prenom | nom | nom_role | + + + + + | Impitoyable | Clint | Eastwood | William Munny | | Impitoyable | Gene | Hackman | Little Bill Dagget | | Van Gogh | Jacques | Dutronc | Van Gogh | | Les pleins pouvoirs | Gene | Hackman | Le pr´esident | + + + + + On a une jointure entre Film et Role, une autre entre Role et Artiste. En ajoutant une jointure entre Artiste et Film, on obtient les metteurs en scène qui ont joué dans leur propre film. mysql> SELECT f.titre, prenom, nom, nom_role -> FROM Film AS f, Role AS r, Artiste -> WHERE f.titre = r.titre -> AND id_acteur = id -> AND id = id_realisateur; + + + + + | titre | prenom | nom | nom_role | + + + + + | Impitoyable | Clint | Eastwood | William Munny | + + + + + Il n’y a pas d’ambiguïté sur les noms d’attributs, à part pour titre, donc il est inutile en l’occurrence d’employer des synonymes. Il existe en revanche une situation où l’utilisation des synonymes est indispensable : celle ou l’on souhaite effectuer une jointure d’une table avec elle-même. Considérons la requête suivante : Donner les paires d’artistes qui sont nés la même année. Ici toutes les informations nécessaires sont dans la seule table Artiste, mais on construit une ligne dans le résultat avec deux lignes de la table. Tout se passe comme si on devait faire la jointure entre deux versions distinctes de la table Artiste. On résout le problème en utilisant deux synonymes distincts (nous omettons le mot-clé AS qui est optionnel). . options de séparation des lignes et des attributs, avec une syntaxe identique à celle utilisée pour LOAD DATA : voir annexe B. 10.2 JOINTURES La jointure est une des opérations les plus utiles (et. les deux cas, définit un « espace de recherche» qui, quand il y a une seule table, correspond à toutes les lignes de celle-ci. Quand il y a deux tables, cet espace de recherche est constitué de. possibles des lignes des deux tables. La figure 10.2 montre toutes ces combinaisons sous la forme d’une table, compre- nant 4 × 5 = 20 lignes construites à partir des 4 lignes de Film et des cinq