这是我当前的查询:
query_posts(array_merge(array('tag' => $pagetag,'meta_key'=>priority,'orderby' =>meta_value, 'order' =>'ASC','paged' => get_query_var('paged'))));
我的问题是查询仅向我显示具有我的“meta_key”值的帖子,这意味着“优先级”不为 NULL。 我怎样才能改进这个查询,以便它仍然按我的 meta_key 排序,但也会显示所有非 NULL 的帖子?
提前致谢!
最佳答案
问题是,只要您在条件中提到 meta_key
,WordPress 就会将 INNER JOIN
添加到 wp_postmeta
表。解决该问题的一种方法是在 order by
子句上添加一个过滤器,如下所示:
function so_orderby_priority($original_orderby_statement) {
global $wpdb;
return "(SELECT $wpdb->postmeta.meta_value
FROM $wpdb->postmeta
WHERE $wpdb->posts.ID = $wpdb->postmeta.post_id
AND $wpdb->postmeta.meta_key = 'priority') ASC";
}
add_filter('posts_orderby', 'so_orderby_priority');
query_posts(
array(
'tag' => $pagetag,
'paged' => get_query_var('paged')
)
);
remove_filter('posts_orderby', 'so_orderby_priority');
注意 MySQL 首先对 NULL 进行排序 - 如果您希望它们最后排序,请尝试这样的操作(假设您所有的优先级按字母顺序排列在 ZZZZZ 之前):
function so_orderby_priority($original_orderby_statement) {
global $wpdb;
return "IFNULL(
(SELECT $wpdb->postmeta.meta_value
FROM $wpdb->postmeta
WHERE $wpdb->posts.ID = $wpdb->postmeta.post_id
AND $wpdb->postmeta.meta_key = 'priority'),
'ZZZZZ') ASC";
}
编辑
这里有更多解释,假设您至少了解一点 SQL。
您的原始 query_posts
导致对数据库运行以下查询:
SELECT wp_posts.*
FROM wp_posts
INNER JOIN wp_term_relationships ON ( wp_posts.id = wp_term_relationships.object_id )
INNER JOIN wp_postmeta ON ( wp_posts.id = wp_postmeta.post_id )
WHERE 1 = 1
AND ( wp_term_relationships.term_taxonomy_id IN ( 3 ) )
AND wp_posts.post_type = 'post'
AND ( wp_posts.post_status = 'publish'
OR wp_posts.post_status = 'private' )
AND ( wp_postmeta.meta_key = 'priority' )
GROUP BY wp_posts.id
ORDER BY wp_postmeta.meta_value ASC
LIMIT 0, 10;
那个 INNER JOIN wp_postmeta
是从你的结果中删除所有没有优先级的帖子的原因。
从您的query_posts
中删除meta_*
相关条件:
query_posts(
array(
'tag' => $pagetag,
'paged' => get_query_var('paged')
)
);
解决了那个问题,但是排序顺序还是错的。新的 SQL 是
SELECT wp_posts.*
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 ( 3 ) )
AND wp_posts.post_type = 'post'
AND ( wp_posts.post_status = 'publish'
OR wp_posts.post_status = 'private' )
GROUP BY wp_posts.id
ORDER BY wp_posts.post_date DESC
LIMIT 0, 10;
posts_orderby
过滤器允许我们更改ORDER BY
子句:wp_posts.post_date DESC
被过滤器返回的内容替换。最终的 SQL 变为:
SELECT wp_posts.*
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 ( 3 ) )
AND wp_posts.post_type = 'post'
AND ( wp_posts.post_status = 'publish'
OR wp_posts.post_status = 'private' )
GROUP BY wp_posts.id
ORDER BY (SELECT wp_postmeta.meta_value
FROM wp_postmeta
WHERE wp_posts.id = wp_postmeta.post_id
AND wp_postmeta.meta_key = 'priority') ASC
LIMIT 0, 10
哪个做你想要的。
关于mysql - Wordpress 按自定义字段查询顺序缺少帖子,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11314896/