Requête SQL : souci avec OR

Petit nouveau ! | 4 Messages

16 avr. 2007, 17:52

Bonjour,

j'ai un petit problème avec ma base que voici :

Table films

Code : Tout sélectionner

+-------+----------+-----------+-----------+-----------+ |film_id|film_titre|film_genre1|film_genre2|film_genre3| +-------+----------+-----------+-----------+-----------+ |1 |Film1 |1 |2 |3 | +-------+----------+-----------+-----------+-----------+ |2 |Film2 |3 |4 | | +-------+----------+-----------+-----------+-----------+
Table genres

Code : Tout sélectionner

+--------+-----------+ |genre_id|genre_titre| +--------+-----------+ |1 |Action | +--------+-----------+ |2 |Aventures | +--------+-----------+ |3 |Fantastique| +--------+-----------+ |4 |Drame | +--------+-----------+

- Je souhaite récupérer les genres caractérisant un film dont je connais l'id, sachant qu'un film peut avoir plusieurs genres. Ma requête est la suivante :

Code : Tout sélectionner

select film_titre, genre_titre from films a, films_genres b where a.film_genre1=b.genre_id or a.film_genre2=b.genre_id or a.film_genre3=b.genre_id and film_id=1
Evidemment la clause or ne convient pas étant donné que le film2 a un genre en commun avec le film1 et me retourne ainsi tout. Mais je ne sais pas comment la remplacer, pourriez vous m'aiguiller? =]

Merci d'avance

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

17 avr. 2007, 04:17

Il te faut enlever les champs "film_genres" de la table "films" et créer une table "films_genres" dont les colonnes seraient ("film_id", "genre_id") et qui servirait à faire le lien entre un film et les différents genres auxquels il appartient. Fais des recherches sur le forum et sur ton moteur de recherche préféré sur les procédés de "normalisation" ou "formes normales".

Ainsi, il devient facile de faire ce que tu recherches:

Code : Tout sélectionner

SELECT f.film_titre, g.genre_titre FROM films f JOIN films_genres fg USING (film_id) JOIN genres g USING (genre_id) WHERE f.film_id = 1
"films" est liée à "films_genres" par la colonne "film_id", et "films_genres" est liée à "genres" par la colonne "genre_id". De cette façon, un film peut avoir de 0 à une infinité de genres sans que tu aies à changer tes requêtes.

Une astuce : définis ("film_id", "genre_id") comme clé primaire et "genre_id" comme index de la table.

Petit nouveau ! | 4 Messages

17 avr. 2007, 09:33

Oki je vois mieux, merci, je me plantais sur la normalisation des clefs étrangères (c'est que je ne fais plus de sql moi ><).

Par contre j'ai une question : USING spécifie le paramètre sur lequel on fait la jointure?

Merci encore

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

17 avr. 2007, 14:10

a JOIN b USING (col) est équivalent à a JOIN b ON (a.col = b.col)

De la même façon,
a JOIN b USING (col1, col2) est équivalent à a JOIN b ON (a.col1 = b.col1 AND a.col2 = b.col2)

Raison supplémentaire de faire attention à garder le même nom de colonne pour les mêmes données. Et puis ça montre clairement que la colonne en question sert de jointure, "a jointe à b par col". Mais sinon les deux sont identiques.

Petit nouveau ! | 4 Messages

18 avr. 2007, 16:32

merci pour le complément d'informations.