Vous devez rejoindre le post_meta
table deux fois. Voici un peu de théorie sur les bases de données.
Lorsque vous joignez des tables, en théorie, une table temporaire contenant tous les éléments de la première table combinés avec tous les éléments de la deuxième table est créée et filtrée. Donc, si, par exemple, vous n'avez qu'un seul élément méta par publication et que vous avez 3 publications, vous avez
+-------+----------+
|post_id|post_title|
+-------+----------+
| 1 | 'Post 1' |
| 2 | 'Post 2' |
| 3 | 'Post 3' |
+-------+----------+
et
+-------+----------+----------+------------+
|meta_id| post_id | meta_key | meta_value |
+-------+----------+----------+------------+
| 10 | 1 | k1 | v1 |
| 11 | 2 | k1 | v2 |
| 12 | 3 | k1 | v3 |
+-------+----------+----------+------------+
Et la table jointe temporaire "théorique" est :
+---------+------------+----------+----------+-----------+-------------+
|p.post_id|p.post_title|pm.meta_id|pm.post_id|pm.meta_key|pm.meta_value|
+---------+------------+----------+----------+-----------+-------------+
| 1 | 'Post 1' | 10 | 1 | k1 | v1 |
| 1 | 'Post 1' | 11 | 2 | k1 | v2 |
| 1 | 'Post 1' | 12 | 3 | k1 | v3 |
| 2 | 'Post 2' | 10 | 1 | k1 | v1 |
| 2 | 'Post 2' | 11 | 2 | k1 | v2 |
| 2 | 'Post 2' | 12 | 3 | k1 | v3 |
| 3 | 'Post 3' | 10 | 1 | k1 | v1 |
| 3 | 'Post 3' | 11 | 2 | k1 | v2 |
| 3 | 'Post 3' | 12 | 3 | k1 | v3 |
+---------+------------+----------+----------+-----------+-------------+
Vous dites alors :WHERE p.id =pm.post_id
et cela filtre la table temporaire comme :
+---------+------------+----------+----------+-----------+-------------+
|p.post_id|p.post_title|pm.meta_id|pm.post_id|pm.meta_key|pm.meta_value|
+---------+------------+----------+----------+-----------+-------------+
| 1 | 'Post 1' | 10 | 1 | k1 | v1 |
| 2 | 'Post 2' | 11 | 2 | k1 | v2 |
| 3 | 'Post 3' | 12 | 3 | k1 | v3 |
+---------+------------+----------+----------+-----------+-------------+
Vous n'avez donc qu'une seule ligne pour chaque publication + méta-valeur. Votre requête demande des lignes qui ont à la fois meta_key = category
et meta_key =book_genre` qui n'existent pas.
Vous avez donc besoin d'une table qui rejoint le postmeta
table en DEUX FOIS.
Vous pouvez le faire en aliasant la table lorsque vous les rejoignez. Pardonnez-moi de simplifier :
SELECT wp_posts.*, pm1.*, pm2.*
FROM
wp_posts
wp_postmeta as pm1
wp_postmeta as pm2
WHERE pm1.post_id = wp_posts.ID
AND pm2.post_id = wp_posts.ID
AND ...etc
Ici, vous avez deux copies jointes de la table postmeta aliasée à pm1
et pm2
(car ils ne peuvent pas TOUS LES DEUX s'appeler wp_postmeta
dans la requête.
Vous pouvez alors demander :
AND pm1.meta_key = 'category'
AND pm1.meta_value = X
AND pm2.meta_key = 'book_genre'
AND pm2.meta_key IN (123,456)
J'espère que vous pourrez assembler le reste à partir de cela.
Je pense aussi que vous pouvez le faire avec WP_Query si vous voulez emprunter cette voie.