Question aux pros du SQL résolue : clause HAVING

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…

Publié par Charlie

Être humain depuis 1986, développeur web, designer et photographe, je code pour le Web depuis 2000 et pour WordPress depuis 2008. Aventure, Histoire, sciences, musique, café ou personnages forts en caractère et dotés d'un nez en tout point remarquable sont parmi mes passions les plus dévorantes. Indépendant depuis 2010 je travaille avec des gens formidables dans le monde entier, de la Californie à l'Europe en passant par l'Australie et l'Asie. D'autres détails croustillants ?

Rejoindre la conversation

1 commentaire

  1. 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’;

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.

*