ฉันพยายามที่จะใช้คำตอบ @Manny Fleurmond และเหมือน @Jake ฉันไม่สามารถได้รับมันในการทำงานแม้หลังจากการแก้ไขพิมพ์ผิดที่ควรจะเป็น'orderby' => 'meta_key'
'orderby' => 'meta_value'
(และเพื่อความสมบูรณ์ก็ควรจะ'posts_per_page'
ได้'post_per_page'
แต่ไม่ได้ส่งผลกระทบต่อปัญหาการถูกมองที่.)
ถ้าคุณดูที่แบบสอบถาม SQL ที่สร้างขึ้นจริงโดยคำตอบของ @Manny Fleurmond (แก้ไขข้อผิดพลาด) นี่คือสิ่งที่คุณได้รับ:
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 ทำการแยกวิเคราะห์ vars แบบสอบถาม: มันกำลังสร้างตารางสำหรับแต่ละ meta_query clause แล้วหาวิธีที่จะเข้าร่วมและสิ่งที่จะสั่งซื้อ การสั่งซื้อจะทำงานได้ดีถ้าคุณใช้เพียงประโยคเดียว'compare' => 'EXISTS'
แต่เข้าร่วม'compare' => 'NOT EXISTS'
ข้อที่สองกับ OR (ตามที่เราต้อง) ทำให้การสั่งซื้อยุ่งเหยิง ผลลัพธ์คือ LEFT JOIN ถูกใช้เพื่อเข้าร่วมทั้ง clause / table แรกและ clause / table ที่สอง - และวิธีที่ WP รวมทุกอย่างเข้าด้วยกันหมายความว่าตารางที่สร้างโดยใช้'compare' => 'EXISTS'
นั้นถูกเติมด้วย meta_values จากฟิลด์ที่กำหนดเองใด ๆ'custom_author_name'
ฟิลด์ที่เราสนใจดังนั้นฉันคิดว่าการเรียงลำดับคำสั่ง / ตารางนั้นจะให้ผลลัพธ์ที่ต้องการหาก post_type เฉพาะของ 'news' มีเฉพาะฟิลด์ที่กำหนดเองเท่านั้น
ทางออกที่ทำงานกับสถานการณ์ของฉันคือการสั่งซื้อโดยข้ออื่น ๆ / ตาราง - ไม่มีอยู่อย่างใดอย่างหนึ่ง ดูเหมือนว่าฉันรู้ตัวง่ายทวน แต่เนื่องจากวิธี WP วิเคราะห์คำ vars แบบสอบถามมันเป็นตารางนี้ที่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 พูดว่ามันเป็นประโยคแรกที่ใช้สำหรับออร์เดอร์บายดังนั้นคำตอบคือเพียงแค่สลับรอบคำสั่งโดยให้สิ่งนี้:
$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'
มันจะเปลี่ยนลำดับ แต่ก็ไม่มีอะไรเกี่ยวข้องกับเขตข้อมูลเมตาจริง