Saya mencoba menerapkan jawaban @Manny Fleurmond dan menyukai @Jake saya tidak bisa membuatnya bekerja bahkan setelah memperbaiki kesalahan ketik yang 'orderby' => 'meta_key'
seharusnya 'orderby' => 'meta_value'
. (Dan untuk kelengkapannya seharusnya 'posts_per_page'
tidak 'post_per_page'
tetapi itu tidak mempengaruhi masalah yang sedang dilihat.)
Jika Anda melihat kueri SQL yang sebenarnya dihasilkan oleh jawaban @Manny Fleurmond (setelah memperbaiki kesalahan ketik) inilah yang Anda dapatkan:
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
Ini menggambarkan cara WP mem-parsing kueri vars: itu membuat tabel untuk setiap klausa meta_query, kemudian mencari cara untuk bergabung dengan mereka dan apa yang harus dipesan. Pemesanan akan berfungsi dengan baik jika Anda hanya menggunakan satu klausa dengan 'compare' => 'EXISTS'
, tetapi bergabung dengan 'compare' => 'NOT EXISTS'
klausa kedua dengan ATAU (karena kami harus) mengacaukan pemesanan. Hasilnya adalah LEFT JOIN digunakan untuk bergabung dengan klausa / tabel pertama dan klausa / tabel kedua - dan cara WP menyatukan semuanya berarti bahwa tabel yang dibuat menggunakan 'compare' => 'EXISTS'
sebenarnya diisi dengan meta_values dari bidang kustom APA PUN, bukan hanya 'custom_author_name'
bidang yang kami minati. Jadi saya pikir memesan dengan klausa / tabel itu hanya akan memberikan hasil yang diinginkan jika post_type khusus dari 'berita' hanya memiliki satu bidang khusus.
Solusi yang bekerja untuk situasi saya adalah memesan dengan klausa lain / tabel - yang TIDAK ADA. Tampaknya kontra-intuitif, saya tahu, tetapi karena cara WP mem-parsing kueri vars inilah tabel ini tempat meta_value
dihuni hanya oleh bidang kustom yang kita kejar.
(Satu-satunya cara saya menemukan ini adalah dengan menjalankan yang setara dengan permintaan ini untuk kasus saya:
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
Yang saya lakukan adalah mengubah kolom yang ditampilkan dan menghapus klausa GROUP BY. Ini kemudian menunjukkan kepada saya apa yang sedang terjadi - bahwa kolom postmeta.meta_value menarik nilai dari semua meta_keys, sedangkan kolom mt1.meta_value hanya menarik meta_values dari bidang kustom berita.)
Solusinya
Seperti yang dikatakan @Manny Fleurmond, ini adalah klausa pertama yang digunakan untuk orderby, jadi jawabannya adalah dengan menukar babak klausa, dengan memberikan ini:
$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);
Atau Anda dapat membuat array asosiatif klausa dan memesan dengan kunci yang sesuai, seperti:
$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'
, itu mengubah urutan, tetapi tidak ada hubungannya dengan bidang meta yang sebenarnya.