@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_query句のテーブルを作成し、それらを結合する方法と並べ替え方法を理解しています。で単一の句のみを使用している場合、順序は適切に機能しますが'compare' => 'EXISTS'
、2番目の'compare' => 'NOT EXISTS'
句をORで結合すると(必要に応じて)、順序が混乱します。結果は、LEFT JOINを使用して最初の句/テーブルと2番目の句/テーブルの両方を結合することです。WPがすべてをまとめる方法は、使用して作成されたテーブルに、'compare' => 'EXISTS'
実際には任意のカスタムフィールドのmeta_values 'custom_author_name'
興味のあるフィールドです。そのため、その句/テーブルによる順序付けは、「news」の特定のpost_typeに1つのカスタムフィールドしかない場合にのみ、望ましい結果が得られると思います。
私の状況で機能した解決策は、他の句/テーブルで注文することでした-NOT EXISTS 1。一見わかりにくいようですが、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句を削除しただけです。これにより、何が起こっているのかがわかりました。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'
、順序は変更されましたが、実際のメタフィールドとは何の関係もありませんでした。