Сортировка по нескольким произвольным полям и их значениям
meta_query
— это массив мета-условий. Например:
$q = new WP_Query( array(
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'state',
'value' => 'Wisconsin',
),
array(
'key' => 'city',
'compare' => 'EXISTS',
),
),
) );
Вы можете использовать ассоциативный массив с ключами для каждого мета-условия:
$q = new WP_Query( array(
'meta_query' => array(
'relation' => 'AND',
'state_clause' => array(
'key' => 'state',
'value' => 'Wisconsin',
),
'city_clause' => array(
'key' => 'city',
'compare' => 'EXISTS',
),
),
) );
Затем эти ключи можно использовать в аргументе order_by
с одним условием:
$q = new WP_Query( array(
'meta_query' => array(
'relation' => 'AND',
'state_clause' => array(
'key' => 'state',
'value' => 'Wisconsin',
),
'city_clause' => array(
'key' => 'city',
'compare' => 'EXISTS',
),
),
'orderby' => 'city_clause', // Результаты будут отсортированы по значениям метаполя 'city'.
) );
Или с несколькими условиями:
$q = new WP_Query( array(
'meta_query' => array(
'relation' => 'AND',
'state_clause' => array(
'key' => 'state',
'value' => 'Wisconsin',
),
'city_clause' => array(
'key' => 'city',
'compare' => 'EXISTS',
),
),
'orderby' => array(
'city_clause' => 'ASC',
'state_clause' => 'DESC',
),
) );
Пример взят из этой записи в блоге Make WordPress Core.

не забудьте указать тип мета-ключа/значения. Это повлияет на результаты. По умолчанию WordPress обрабатывает ваши метаданные как строку.

Но что если я хочу получить не только результаты по штату Висконсин? Мне нужны все штаты, включая строки, где город может быть или не быть указан, с сортировкой по этим двум полям. То есть вообще без WHERE - только ORDER BY.

Феликс, при таких требованиях можно использовать обходное решение - добавить завершающий "ловущий всё" пункт в ваш meta_query и поместить его последним в порядке сортировки. Первые несколько условий в meta_query будут получать конкретные результаты, которые вы хотите видеть в начале. А последнее условие будет включать всё, что не попало под предыдущие условия.

EXISTS
— это отличный способ получить сложный именованный мета-запрос, но при этом не фильтровать по значению :)
Кстати: у меня был реальный кейс — нужно было отсортировать события по дате DESC, но по времени ASC, используя одно поле даты&времени. Я использовал документацию и этот ответ, чтобы построить это: https://ideone.com/RUoyZs :-)
