Comme le titre l’indique, une question aux gens qui déchirent en base de données 🙂
J’ai une table SQL pour WordPress, qui contient 4 colonnes : meta_id, post_id, meta_key, meta_value. C’est la table postmeta, même si ça n’est pas important en soi. Admettons que j’ai les valeurs suivantes :
meta_id | post_id | meta_key | meta_value ---------+-----------+------------+--------------------- 1 | 1541 | 'acteur' | 'Johnny Depp' 2 | 1541 | 'acteur' | 'Helena B. Carter' 3 | 1684 | 'acteur' | 'Alan Rickman' 4 | 1684 | 'acteur' | 'Kevin Costner' 5 | 6843 | 'acteur' | 'Johnny Depp' 6 | 6843 | 'acteur' | 'Helena B. Carter' 7 | 3184 | 'acteur' | 'Sam Neil' 8 | 3184 | 'acteur' | 'Helena B. Carter'
Je veux récupérer les articles pour lesquels on a ‘Johnny Depp’ et ‘Helena B. Carter’, c’est-à-dire les post_id 1541 et 6843. Comment je récupère ça en une seule requête SQL ?
L’idée est de faire un formulaire de recherche qui me permettrait de trouver par exemple des films en fonction d’une liste d’acteurs ayant joué dedans. Il me semble qu’il y a un moyen simple de faire ça, mais je n’ai pas encore remis la main dessus.
Bon, il faut voir aussi niveau performance. À terme, il n’est pas impossible qu’il faille effectuer les requêtes avec deux, trois, cinq ou six acteurs ; dans ce cas il vaudra probablement mieux effectuer toutes les requêtes séparément et les croiser en PHP pour n’obtenir que les fiches de films ou les acteurs apparaissent tous ; ou alors diviser, et croiser les requêtes deux par deux…
Bref, c’est ouvert aux suggestions 🙂
Édition 1er décembre 18h12 :
Solution apportée par François : la clause HAVING.
SELECT post_id, COUNT(*) AS nb FROM postmeta WHERE meta_key = 'acteur' AND meta_value IN( 'Johnny Depp', 'Helena B. Carter' ) GROUP BY post_id HAVING nb = 2
Avec possibilité d’augmenter le nombre d’acteurs en changeant HAVING nb = i
, voire même HAVING nb >= i
pour obtenir les films où apparaissent au moins i
acteurs…
Mouais. Je connaissais pas du tout cette écriture. J’aurais su faire que des jointures, qui seraient peut-être un lourdes pour plus de deux acteurs…
SELECT post_id
FROM postmeta AS t1, postmeta AS t2
WHERE t1.post_id = t2.post_id
AND t1.meta_value LIKE ‘Johnny Depp’
AND t2.meta_value LIKE ‘Helena B. Carter’;