Usando Orderby y meta_value_num para ordenar los números primero y luego las cadenas

16

Tengo una lista de productos, cada uno con un precio en un campo personalizado almacenado como texto como "2.50" o "5.00" y los estoy mostrando en la página con una consulta personalizada que se clasifica por el precio:

    if(!$wp_query) {
        global $wp_query;
    }

    $args = array(
        'meta_key' => 'price',
        'orderby' => 'meta_value_num',
        'order' => 'ASC'
    );

    query_posts( array_merge( $args , $wp_query->query ) );

Esto funciona bien para los precios, pero algunos precios son "POA" y me gustaría mostrarlos al final, sin embargo, los pedidos anteriores de tal manera que "POA" se muestra primero.

¿Hay alguna forma de alterar esto, o un truco rápido que podría usar para ordenar la matriz después y poner los precios "POA" al final?

Shaun
fuente
intenta cambiar 'orderby' => 'meta_value_num', a'orderby' => 'meta_value_num meta_value',
Bainternet
Gracias pero eso no funciona :(
Shaun
¡Ajá! ¡Pero al revés funciona meta_value meta_value_num! ¡Gracias! ¿Quieres escribir una respuesta para que pueda votarla?
Shaun
1
publicado como respuesta para personas que no leen comentarios.
Bainternet
POA significa "precio al preguntar" en.wikipedia.org/wiki/Price_on_application
sudip

Respuestas:

23

El OrderByargumento puede tomar más de un parámetro, por lo que la solución fue cambiar:

'orderby' => 'meta_value_num',

a:

'orderby' => 'meta_value meta_value_num',
Bainternet
fuente
3
Esto solo se ordena alfabéticamente, ya que el segundo parámetro es un no-op, ordenando en el mismo campo sin ningún efecto. Para hacer esto, de modo que los números se ordenen numéricamente y los alfa alfabéticamente, debería usar un filtro para personalizar el orden para usar algún tipo de carcasa SQL, por ejemploORDER BY CASE WHEN wp_postmeta.meta_value RLIKE '^[0-9]' THEN '' ELSE wp_postmeta.meta_value END ASC, wp_postmeta.meta_value+0 ASC
bonger
@bonger ¡Gracias! Su solución es la solución completa para este problema. Y aquí está el resto del código donde se coloca su consulta. Voy a publicarlo como respuesta para nuevos visitantes.
Gangesh
2

Encontré esta solución combinando código de @bonger y /programming/18084199/wordpress-query-order-by-case-when

Y funciona bien.

Función

function filter_case($orderby = '') {
  $orderby .= "CASE WHEN wp_postmeta.meta_value RLIKE '^[0-9]' THEN '' ELSE wp_postmeta.meta_value END ASC, wp_postmeta.meta_value+0 ASC";
  return $orderby;
}

Antes de la consulta

add_filter( 'posts_orderby', 'filter_case' );

$wp_query = new WP_Query($args);

remove_filter( 'posts_orderby', 'filter_case' );
Gangesh
fuente