Tôi đã cố gắng áp dụng câu trả lời @Manny Fleurmond và như @Jake tôi không thể làm cho nó làm việc ngay cả sau khi sửa chữa các lỗi đánh máy mà 'orderby' => 'meta_key'
nên 'orderby' => 'meta_value'
. (Và cho đầy đủ nó phải 'posts_per_page'
không 'post_per_page'
nhưng điều đó không ảnh hưởng đến vấn đề này đang được xem xét.)
Nếu bạn nhìn vào truy vấn SQL thực sự được tạo bởi câu trả lời của @Manny Fleurmond (đã sửa lỗi chính tả) thì đây là những gì bạn nhận được:
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
Điều này minh họa cách WP phân tích các vars truy vấn: nó tạo một bảng cho mỗi mệnh đề meta_query, sau đó tìm ra cách tham gia chúng và sắp xếp thứ tự. Việc đặt hàng sẽ hoạt động tốt nếu bạn chỉ sử dụng một mệnh đề duy nhất với 'compare' => 'EXISTS'
, nhưng việc kết hợp 'compare' => 'NOT EXISTS'
mệnh đề thứ hai với OR (như chúng ta phải) làm rối trật tự. Kết quả là LEFT THAM GIA được sử dụng để tham gia cả mệnh đề / bảng đầu tiên và mệnh đề / bảng thứ hai - và cách WP đặt mọi thứ lại với nhau có nghĩa là bảng được tạo bằng cách sử dụng 'compare' => 'EXISTS'
thực sự được điền với meta_values từ bất kỳ trường tùy chỉnh nào, không chỉ 'custom_author_name'
trường chúng tôi quan tâm. Vì vậy, tôi nghĩ rằng việc đặt hàng theo mệnh đề / bảng đó sẽ chỉ cho kết quả mong muốn nếu post_type cụ thể của 'news' chỉ có một trường tùy chỉnh duy nhất.
Giải pháp hiệu quả cho tình huống của tôi là đặt hàng theo mệnh đề / bảng khác - không phải là EXISTS. Tôi dường như phản trực giác, nhưng vì cách WP phân tích cú pháp truy vấn, đây là bảng meta_value
chỉ được điền bởi trường tùy chỉnh mà chúng ta đang theo dõi.
(Cách duy nhất tôi tìm ra điều này là bằng cách chạy tương đương với truy vấn này cho trường hợp của tôi:
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
Tất cả những gì tôi đã làm là thay đổi các cột được hiển thị và xóa mệnh đề GROUP BY. Điều này sau đó cho tôi thấy những gì đang diễn ra - rằng cột postmeta.meta_value đang kéo các giá trị từ tất cả các meta_keys, trong khi cột mt1.meta_value chỉ kéo theo meta_values từ trường tùy chỉnh tin tức.)
Giải pháp
Như @Manny Fleurmond nói, đây là mệnh đề đầu tiên được sử dụng cho người đặt hàng, vì vậy câu trả lời chỉ là hoán đổi vòng mệnh đề, đưa ra điều này:
$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);
Ngoài ra, bạn có thể tạo các mệnh đề liên kết mảng và sắp xếp theo khóa tương ứng, như vậy:
$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'
, nó đã thay đổi thứ tự, nhưng nó không liên quan gì đến trường meta thực tế.