問題
WP_Query
を使って カスタムフィールドの値がゼロ または 値が設定されていない 投稿を取得したかったけど、何度 meta_query
を見直しても取得できなかった
動かなかった $args
$args = [
'post_type' => 'custom_post_type',
'post_status' => 'publish',
'meta_query' => [
'relation' => 'AND',
[
'key' => 'custom_field_1',
'value' => 'A',
],
[
'relation' => 'OR',
[
'key' => 'custom_field_target',
'value' => '0',
],
[
'key' => 'custom_field_target',
'compare' => 'NOT EXISTS',
],
]
],
'orderby' => 'meta_value',
'meta_key' => 'custom_field_target',
'order' => 'ASC',
'posts_per_page' => -1,
];
これの何がいけないかわかります…?
解決
'orderby' => 'meta_value',
'meta_key' => 'custom_field_target',
これが悪さをしていました。実装上、不要な orderby なので削除したら動くように。
原因
生成されたクエリを読んでいると、 'orderby' => 'meta_value'
が指定されていると、
SELECT
wp_posts.*
FROM
wp_posts
/* ↓ meta_value で orderby するための JOIN */
LEFT JOIN wp_postmeta ON (
wp_posts.ID = wp_postmeta.post_id
)
/* ↓ meta_query のための JOIN */
LEFT JOIN wp_postmeta AS mt1 ON (wp_posts.ID = mt1.post_id)
/*...中略...*/
WHERE
1 = 1
AND (
wp_postmeta.meta_key = 'custom_field_target' /* !! */
AND (
/* ここに meta_query で指定した条件 */
)
)
/*...略...*/
…というクエリになるので、NOT EXISTS
を使っても無意味になる、と。