Ordenar por múltiples claves meta y valores meta
meta_query
es un array de cláusulas de metadatos. Por ejemplo:
$q = new WP_Query( array(
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'state',
'value' => 'Wisconsin',
),
array(
'key' => 'city',
'compare' => 'EXISTS',
),
),
) );
Puedes usar un array asociativo, con una clave para cada cláusula de metadatos:
$q = new WP_Query( array(
'meta_query' => array(
'relation' => 'AND',
'state_clause' => array(
'key' => 'state',
'value' => 'Wisconsin',
),
'city_clause' => array(
'key' => 'city',
'compare' => 'EXISTS',
),
),
) );
Luego, puedes usar esas claves en el argumento order_by
, con una:
$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', // Los resultados se ordenarán por los valores de metadatos 'city'.
) );
O más cláusulas:
$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',
),
) );
Ejemplo tomado de esta publicación en el blog Make WordPress Core.

no olvides agregar el tipo de la clave/valor meta. Esto afectará los resultados. Por defecto, WordPress tratará tu meta como una cadena.

Pero, ¿qué pasa si no solo quiero devolver resultados donde el estado es Wisconsin? Quiero que se devuelvan todos los estados y quiero filas donde pueda o no haber una ciudad y aún así ordenar por esos 2 campos. Por ejemplo, sin ninguna cláusula WHERE, solo un ORDER BY.

Felix, con esos requisitos, una solución alternativa podría ser incluir una cláusula final 'catch all' en tu meta_query, y colocarla al final en tu declaración orderby. Así, las primeras cláusulas en tu meta_query obtendrían los resultados específicos que deseas ordenar primero. Luego, tu última cláusula sería todo lo que no sean tus cláusulas anteriores.

EXISTS
es una forma genial de obtener la consulta de metadatos con nombres complejos pero al mismo tiempo no filtrar por el valor :)
Por cierto: tuve un caso de uso real - el requerimiento era ordenar eventos por fecha DESC pero hora ASC usando un solo campo de fecha&hora Usé la documentación y esta respuesta para construir esto: https://ideone.com/RUoyZs :-)
