使用 IN 根据多个元键/值对获取 WP 帖子
我在格式化查询以根据两个元值的值从数据库获取帖子列表时遇到一些问题。我使用的是 WordPress 4.9.4,我需要使用 $wpdb->get_results()
而不是普通的 get_posts()
函数带参数调用。
这是我到目前为止所得到的,但如果我尝试在 MySQL 查询中包含 IN
部分,它不会返回任何内容,但它应该返回至少一篇文章。
global $wpdb;
$posts = $wpdb->get_results(
$wpdb->prepare(
'SELECT ' . $wpdb->prefix . 'posts.*, ' . $wpdb->prefix . 'postmeta.* FROM ' . $wpdb->prefix . 'posts, ' . $wpdb->prefix . 'postmeta WHERE ' . $wpdb->prefix . 'posts.post_type = %s AND ' . $wpdb->prefix . 'postmeta.post_id = ' . $wpdb->prefix . 'posts.ID AND (' . $wpdb->prefix . 'postmeta.meta_key = %s AND ' . $wpdb->prefix . 'postmeta.meta_value = %s) AND (' . $wpdb->prefix . 'postmeta.meta_key = %s AND ' . $wpdb->prefix . 'postmeta.meta_value IN (%s)) ORDER BY ' . $wpdb->prefix . 'posts.post_title ASC LIMIT %d OFFSET %d',
'book',
'book_genre',
$genre,
'category',
'239, 440',
$limit,
$offset
)
);
上述查询应获取所有帖子,其中:
- 帖子在
wp_posts
中的post_type
为book
, - meta_key 为
book_genre
> 且wp_postmeta
中fiction
的 meta_value 的 - meta_key 为
category
,meta_value 为239,
wp_postmeta
中的 440 - 将结果限制为
xyz
- 偏移结果
xyz
但是,上述查询返回值 null< /code> 如果我
var_dump( $posts );
到页面上,所以我想这部分可能会导致与第一个元键/值规则发生某种冲突?
如果我删除查询的 IN
部分,它会按预期获得所有内容,减去我想要的类别的过滤。类别 id 是一个 id 数组,使用 PHP 的 implode()
将其转换为逗号分隔的字符串。
例如:
Post
1
的 post_type 为book
,元键/值对为book_genre
和fiction< /code> 并具有“category”和
440
元键/值对,因此使用上述查询应包含。Post
2
的 post_type 为book
,元键/值对为book_genre
和fiction
并且具有“category”和323
的元键/值对,因此不应使用上述查询包含在内。
I'm having some trouble formatting my query to fetch a list of posts from the database based on the value of two meta values. I'm using WordPress 4.9.4 and I need to use $wpdb->get_results()
and not a normal get_posts()
function call with arguments.
Here is what I have so far, but if I try and include the IN
part in the MySQL query, it doesn't return anything but it should return at least one post.
global $wpdb;
$posts = $wpdb->get_results(
$wpdb->prepare(
'SELECT ' . $wpdb->prefix . 'posts.*, ' . $wpdb->prefix . 'postmeta.* FROM ' . $wpdb->prefix . 'posts, ' . $wpdb->prefix . 'postmeta WHERE ' . $wpdb->prefix . 'posts.post_type = %s AND ' . $wpdb->prefix . 'postmeta.post_id = ' . $wpdb->prefix . 'posts.ID AND (' . $wpdb->prefix . 'postmeta.meta_key = %s AND ' . $wpdb->prefix . 'postmeta.meta_value = %s) AND (' . $wpdb->prefix . 'postmeta.meta_key = %s AND ' . $wpdb->prefix . 'postmeta.meta_value IN (%s)) ORDER BY ' . $wpdb->prefix . 'posts.post_title ASC LIMIT %d OFFSET %d',
'book',
'book_genre',
$genre,
'category',
'239, 440',
$limit,
$offset
)
);
The above query should get all posts where:
- the post has a
post_type
ofbook
inwp_posts
- has a meta_key of
book_genre
and meta_value offiction
inwp_postmeta
- has a meta_key of
category
and meta_value of239, 440
inwp_postmeta
- limit results to
xyz
- offset results of
xyz
However, the above query returns a value of null
if I var_dump( $posts );
onto the page, so I imagine that the in part is causing some sort of conflict with the first meta key/value rule, perhaps?
If I remove the IN
part of the query it gets everything as expected minus the filtering of the categories of course that I'd like. The category ids are an array of ids that are converted into a comma-separated string using PHP's implode()
.
For example:
Post
1
has a post_type ofbook
, has a meta key/value pair ofbook_genre
andfiction
and has a meta key/value pair of 'category' and440
so should be included using the above query.Post
2
has a post_type ofbook
, has a meta key/value pair ofbook_genre
andfiction
and has a meta key/value pair of 'category' and323
so should not be included using the above query.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您需要加入
post_meta
表两次。这是一些数据库理论。当您连接表时,理论上会创建一个临时表,该临时表包含第一个表中的所有项目以及第二个表中的所有项目。因此,例如,如果每个帖子只有 1 个元项目,并且有 3 个帖子,那么您就拥有了
并且
“理论”临时连接表是:
然后您说: WHERE p.id = pm.post_id
这会过滤临时表为:
因此,每个帖子 + 元值只有一行。您的查询要求提供同时具有
meta_key = Category
和 meta_key = book_genre` 的行,但这些行都不存在。因此,您需要一个在 TWICE 中连接
postmeta
表的表。您可以通过在连接表时为表添加别名来完成此操作。请原谅我的简化:
这里有两个 postmeta 表的连接副本,别名为
pm1
和pm2
(因为它们不能同时称为wp_postmeta 在查询中,
然后您可以询问:
希望您可以将其余部分拼接起来,
如果您想走这条路,我也认为您可以使用 WP_Query 来完成此操作。
You need to join the
post_meta
table twice. Here's some database theory.When you join tables, in theory a temporary table contains all of the items from the first table combined with all of the items from the second table is created and filtered. So if, for example, you have just 1 meta item per post, and you have 3 posts then you have
and
And the "theoretical" temporary joined table is:
You then say: WHERE p.id = pm.post_id
and this filters the temporary table to be:
So you only have one row for each post + meta value. Your query is asking for rows that have both
meta_key = category
and meta_key = book_genre` which don't exist.So you need a table that joins the
postmeta
table in TWICE.You can do this by aliasing the table as you join them. Forgive me for simplifying:
Here you have two joined copies of the postmeta table aliased to
pm1
andpm2
(as they can't BOTH be calledwp_postmeta
in the query.You can then ask for:
Hopefully you can stitch together the rest from that.
I also think you can do this with WP_Query if you want to go that route.