Requête de recherche

Eléphanteau du PHP | 38 Messages

17 sept. 2013, 17:43

Bonjour,

Je suis en train de faire un moteur de recherche sur des films pour les rechercher par genre, et j'ai pas réussit à faire autrement qu'avec des sous requêtes, est ce qu'il y a moyen de faire plus simple et performant en une seule requête ?

Ma requête ci dessous : Rechercher les films qui ont le genre action (id 1) ET le genre aventure (id 2).

Mes tables (simplifiées) :
films
- id
- titre

films_genre
- id_film
- id_genre
SELECT * 
FROM films AS f 
WHERE (SELECT COUNT(id_film) FROM films_genre AS fg WHERE f.id = fg.id_film AND fg.id_genre = 1) > 0 
AND (SELECT COUNT(id_film) FROM films_genre AS fg WHERE f.id = fg.id_film AND fg.id_genre = 2) > 0 
GROUP BY f.id
Merci d'avance :)

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

18 sept. 2013, 07:07

Salut,

Ton modèle n'est pas bon c'est film qui porte la relation avec film_genre et pas l'inverse.
La tu as un genr par film or il y a de grande chance pour que plusieurs films aient le même genre (sinon ta base est bien pauvre.

Du coup
film
id_film
id_genre
titre
Etc

Film_genre
id_genre
Nomgenre

La requête devient
Select * from film join film_genre using(id_genre) where id_genre in (....);
Order by nomgenre
Dans le in tu met les id des genres voulu ;)

@+
Il en faut peu pour être heureux ......

Eléphanteau du PHP | 38 Messages

18 sept. 2013, 14:21

Merci de la réponse mais on a du mal se comprendre ^^

Ma table films_genre est la table de correspondance entre mes genres et mes films. Donc un film n'a pas qu'un seule genre.
Exemple, pour le film avec l'id 1;
id_film,id_genre
1,1 (film id 1, genre id 1)
1,2 (film id 1, genre id 2).

Le film 1 a donc 2 genres : 1 et 2 (action et aventure).

Mais dans l'exemple que tu me proposes, tu mets id_genre dans la table des films, la par contre, un film ne peut avoir qu'un seul genre !

J'ai donc mes films
films
- id
- titre

films_genre
- id_film
- id_genre

et une liste de genres sous forme de variable php : $_FILMS_GENRES = array(1=>'Action', 2=>'Aventure'....);

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

18 sept. 2013, 18:05

ha ok, le principe est identique, mais select sur film_genre et jointure sur film
SELECT * FROM film_genre JOIN film USING(id_film) WHERE id_genre IN (....);


tu select le contenu des deux tables qui satisfont la jointure et dont id_genre et ceux indiqués dans la clause in ;)

@+
Il en faut peu pour être heureux ......

Eléphanteau du PHP | 38 Messages

18 sept. 2013, 18:09

Ahhh je vois ou tu voulais en venir !

Bon après j'suis con, j'aurai du tout expliquer depuis le début, je voulais faire simple pour pas compliquer les choses ...

A l'origine c'est un moteur de recherche ou tu fais une recherche sur plusieurs critères comme le titre du film, l'année et tout. Du coup faut absolument que la requête soit faite sur la table films avec une liaison possible sur la table genres :( désolé !

Et en faisant ça, quand je fais un WHERE films_genre.id_genre IN(1,2) ça me sorte les films qui ont soit aventure soit action mais pas les films qui ont action ET aventure :/

Eléphanteau du PHP | 38 Messages

20 sept. 2013, 12:32

Je reformule mon soucis plus clairement en espérant que ce soit compréhensible ^^

J'ai fait un moteur de recherche sur des films et je suis bloqué sur une requête :

Retourner les films qui ont pour année 2010 et qui ont pour genre action ET aventure. Ça me sort les films qui ont action OU aventure.

J'ai donc mes films
films
- id
- titre
- annee
...

films_genre (table de liaison entre les films et les genres)
- id_film
- id_genre
...

et une liste de genres sous forme de variable php : $_FILMS_GENRES = array(1=>'Action', 2=>'Aventure'....);

Voici ma requête
SELECT * 
FROM films AS f, films_genre AS fg 
WHERE f.id = fg.id_film
AND f.annee = 2010 
AND fg.id_genre IN(1,2)
GROUP BY f.id
Si quelqu'un a la solution, je suis preneur !

Merci :)

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

22 sept. 2013, 22:28

id_genre = 1 and id_genre=2

Tu peux gérer dynamiquement les "and" pour avoir autant de genre que voulut


@+
Il en faut peu pour être heureux ......

Invité
Invité n'ayant pas de compte PHPfrance

30 sept. 2013, 09:59

Bonjour,
donc, il faut que ton films éxiste dans les 2 genres :
select films.* from films where id in(
SELECT f.id,count(*) compte
FROM films AS f, films_genre
WHERE f.id = fg.id_film
AND f.annee = 2010
AND fg.id_genre IN(1,2)
GROUP BY f.id
having count(*)=2) /* ici c'est 2,c'est le nombre de critères de la clause IN (...) */

antoine94200
Invité n'ayant pas de compte PHPfrance

30 sept. 2013, 10:05

pardon, une petite erreur :
SELECT films.* FROM films WHERE id IN(
SELECT f.id
FROM films AS f, films_genre
WHERE f.id = fg.id_film
AND f.annee = 2010
AND fg.id_genre IN(1,2)
GROUP BY f.id
HAVING count(*)=2) /* ici c'est 2,c'est le nombre de critères de la clause IN (...) */

Antoine