Click here or hit escape to close this.

Question aux pros du SQL résolue : clause HAVING

Notice: this post is 6 years old, its content may be outdated.

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…