这里的问题是WP_Query
要求返回的帖子既在帖子ID列表中,又在其中一个类别中。代码生成的SQL查询如下所示:
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) WHERE 1=1 AND wp_posts.ID IN (8200,3581,38,1562,7613) AND ( wp_term_relationships.term_taxonomy_id IN (28,34) ) AND wp_posts.post_type = \'post\' AND (wp_posts.post_status = \'publish\') GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 10
而运行查询所需的是:
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) WHERE 1=1 AND (( wp_term_relationships.term_taxonomy_id IN (28,34) ) OR wp_posts.ID IN (8200,3581,38,1562,7613)) AND wp_posts.post_type = \'post\' AND (wp_posts.post_status = \'publish\') GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 10
在我看来,最优雅的解决方案是删除
posts__in
关键字,并注入适当的SQL(即类别查询和post查询之间的包装或区别),以便最终的SQL语句与上面的SQL语句匹配,如下所示:
add_filter( \'posts_where\' , \'my_posts_where\' );
function my_posts_where( $where ) {
$where = ... // code to inject the OR statement and wrap
return $where;
}
query_posts( array ( \'category__in\' => array( 28, 34 )) );
remove_filter( \'posts_where\' , \'my_posts_where\' );
这可能涉及到相当多的字符串损坏,因此更简单的解决方案可能是简单地查询
$wpdb
直接像这样:
global $wpdb;
$sql = $wpdb->prepare("SELECT SQL_CALC_FOUND_ROWS $wpdb->posts.ID FROM $wpdb->posts INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) WHERE 1=1 AND (( $wpdb->term_relationships.term_taxonomy_id IN (28,34) ) OR $wpdb->posts.ID IN (8200,3581,38,1562,7613)) AND $wpdb->posts.post_type = \'post\' AND ($wpdb->posts.post_status = \'publish\') GROUP BY $wpdb->posts.ID ORDER BY $wpdb->posts.post_date DESC LIMIT 0, 10");
$posts = $wpdb->query($sql);
当然,这个解决方案将返回一个posts列表,而不是iterable
WP_Query
对象如果需要在模板查询中使用此选项
posts_where
上面描述的过滤函数可能是最好的解决方案。