我尝试应用@Manny Fleurmond的答案,就像@Jake一样,即使更正了'orderby' => 'meta_key'
应该的错字,我也无法使它正常工作'orderby' => 'meta_value'
。(出于完整性考虑,应该'posts_per_page'
不是,'post_per_page'
但这不会影响正在研究的问题。)
如果您查看由@Manny Fleurmond的答案实际生成的SQL查询(已纠正输入错误),那么您将获得:
SELECT wp_{prefix}_posts.* FROM wp_{prefix}_posts
LEFT JOIN wp_{prefix}_postmeta ON (wp_{prefix}_posts.ID = wp_{prefix}_postmeta.post_id AND wp_{prefix}_postmeta.meta_key = 'custom_author_name' )
LEFT JOIN wp_{prefix}_postmeta AS mt1 ON ( wp_{prefix}_posts.ID = mt1.post_id )
WHERE 1=1 AND (
wp_{prefix}_postmeta.post_id IS NULL
OR
mt1.meta_key = 'custom_author_name'
) AND wp_{prefix}_posts.post_type = 'news' AND
(wp_{prefix}_posts.post_status = 'publish' OR wp_{prefix}_posts.post_author = 1 AND wp_{prefix}_posts.post_status = 'private')
GROUP BY wp_{prefix}_posts.ID ORDER BY wp_{prefix}_postmeta.meta_value ASC
这说明了WP解析查询var的方式:它为每个meta_query子句创建一个表,然后弄清楚如何联接它们以及如何排序。如果仅使用带有的子句'compare' => 'EXISTS'
,但是将第二个'compare' => 'NOT EXISTS'
子句与OR结合使用(必须如此),则排序工作会很好。结果是使用LEFT JOIN来连接第一个子句/表和第二个子句/表-WP将所有内容放在一起的方式意味着'compare' => 'EXISTS'
实际上使用ANY自定义字段中的meta_values填充了使用创建的表,而不仅仅是'custom_author_name'
因此,我认为如果“ news”的特定post_type仅具有单个自定义字段,则按该子句/表进行的排序将仅提供所需的结果。
适用于我的情况的解决方案是按另一个子句/表排序-NOT EXISTS一个。我知道这似乎违反直觉,但是由于WP分析查询var的方式,该表meta_value
仅由我们所需要的自定义字段填充。
(我发现此问题的唯一方法是针对我的情况运行此查询的等效项:
SELECT wp_{prefix}_posts.ID, wp_{prefix}_postmeta.meta_value, mt1.meta_value FROM wp_{prefix}_posts
LEFT JOIN wp_{prefix}_postmeta ON (wp_{prefix}_posts.ID = wp_{prefix}_postmeta.post_id AND wp_{prefix}_postmeta.meta_key = 'custom_author_name' )
LEFT JOIN wp_{prefix}_postmeta AS mt1 ON ( wp_{prefix}_posts.ID = mt1.post_id )
WHERE 1=1 AND (
wp_{prefix}_postmeta.post_id IS NULL
OR
mt1.meta_key = 'custom_author_name'
) AND wp_{prefix}_posts.post_type = 'news' AND
(wp_{prefix}_posts.post_status = 'publish' OR wp_{prefix}_posts.post_author = 1 AND wp_{prefix}_posts.post_status = 'private')
ORDER BY wp_{prefix}_postmeta.meta_value ASC
我所做的只是更改了显示的列并删除了GROUP BY子句。然后,这向我展示了正在发生的情况-postmeta.meta_value列从所有meta_keys中提取值,而mt1.meta_value列仅从新闻自定义字段中提取meta_values。)
解决方案
就像@Manny Fleurmond所说的,这是用于orderby的第一个子句,因此答案只是交换子句,给出以下内容:
$args = array(
'post_type' => 'news',
'orderby' => 'meta_value',
'order' => 'ASC',
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'custom_author_name',
'compare' => 'NOT EXISTS'
),
array(
'key' => 'custom_author_name',
'compare' => 'EXISTS'
)
),
'posts_per_page' => -1
);
$query = new WP_Query($args);
或者,您可以通过相应的键使子句关联数组和顺序,如下所示:
$args = array(
'post_type' => 'news',
'orderby' => 'not_exists_clause',
'order' => 'ASC',
'meta_query' => array(
'relation' => 'OR',
'exists_clause' => array(
'key' => 'custom_author_name',
'compare' => 'EXISTS'
),
'not_exists_clause' => array(
'key' => 'custom_author_name',
'compare' => 'NOT EXISTS'
)
),
'posts_per_page' => -1
);
$query = new WP_Query($args);
'orderby' => 'meta_value'
,它确实改变了顺序,但是与实际的meta字段无关。