Mysql
 sql >> Base de données >  >> RDS >> Mysql

Obtenez des messages WP basés sur plusieurs paires méta clé/valeur en utilisant IN

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.