我试着用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解析查询变量的方式:它为每个meta\\u查询子句创建一个表,然后确定如何连接它们以及按什么排序。如果只使用一个子句
\'compare\' => \'EXISTS\'
, 但加入第二个
\'compare\' => \'NOT EXISTS\'
带有或(我们必须)的条款打乱了订货。结果是,左连接用于连接第一个子句/表和第二个子句/表,而WP将所有内容放在一起的方式意味着使用
\'compare\' => \'EXISTS\'
实际上使用来自任何自定义字段的meta\\u值填充,而不仅仅是
\'custom_author_name\'
我们感兴趣的领域。因此,我认为,如果特定的post\\u类型的“news”只有一个自定义字段,那么按该子句/表排序只能得到所需的结果。
对我的情况有效的解决方案是按另一个子句/表排序-不存在的那一个。我知道这似乎有违直觉,但由于WP解析查询变量的方式,这张表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子句。这让我知道了发生了什么事,那就是邮差。meta\\u value列从所有meta\\u键中提取值,而mt1。meta\\u value列仅从news自定义字段中提取meta\\u值。)
The Solution
正如@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);