Я спробував застосувати відповідь @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 аналізує варіювання запитів: це створення таблиці для кожного пункту meta_query, а потім з'ясування способів їх приєднання та до чого замовити. Упорядкування буде добре працювати, якби ви використовували лише один пункт із 'compare' => 'EXISTS'
, але приєднання другого 'compare' => 'NOT EXISTS'
пункту з АБО (як ми повинні) зіпсує замовлення. Результат полягає в тому, що LEFT JOIN використовується для приєднання як першого пункту / таблиці, так і другого пункту / таблиці - і те, як WP поєднує все, означає, що таблиця, створена за допомогою 'compare' => 'EXISTS'
, насправді заповнюється мета-значеннями з будь-якого спеціального поля, а не лише з 'custom_author_name'
поле, яке нас цікавить. Тому я думаю, що впорядкування за цим пунктом / таблицею дасть бажані результати лише в тому випадку, якщо конкретний пост_тип 'новини' має лише одне спеціальне поле.
Рішення, яке спрацювало в моїй ситуації, було замовлення за іншим пунктом / таблицею - НЕ ІСНУЄ. Я, здається, неінтуїтивно зрозумілий, але через те, як 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 тягне лише мета-значення з користувацького поля новин.)
Рішення
Як каже @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'
, він змінив порядок, але це не мало нічого спільного з фактичним метаполем.