Usando Orderby e meta_value_num para ordenar os números primeiro e depois as strings

16

Tenho uma lista de produtos, cada um com um preço em um campo personalizado armazenado como texto como "2,50" ou "5,00" e estou exibindo-os na página com uma consulta personalizada que classifica pelo preço:

    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 ) );

Isso funciona bem para os preços, mas alguns são "POA" e eu gostaria de mostrá-los por último, no entanto, os pedidos acima são feitos de maneira que "POA" seja exibido primeiro.

Existe alguma maneira de alterar isso ou um hack rápido que eu poderia usar para classificar a matriz posteriormente e colocar os preços de "POA" por último?

Shaun
fonte
tente mudar 'orderby' => 'meta_value_num', para'orderby' => 'meta_value_num meta_value',
Bainternet
Obrigado, mas isso não funciona :(
Shaun
Aha! Mas o contrário funciona meta_value meta_value_num! Obrigado! Deseja escrever uma resposta para que eu possa votar?
Shaun
1
publicado como resposta para pessoas que não lêem comentários.
Bainternet
POA significa "preço ao pedir" en.wikipedia.org/wiki/Price_on_application
sudip

Respostas:

23

O OrderByargumento pode levar mais de um parâmetro, portanto a solução foi alterada:

'orderby' => 'meta_value_num',

para:

'orderby' => 'meta_value meta_value_num',
Bainternet
fonte
3
Isso apenas classifica em ordem alfabética, pois o segundo parâmetro é no-op, classificando no mesmo campo sem efeito. Para fazer isso para que os números espécie numericamente e os alfas alfabeticamente você teria que usar um filtro para personalizar o orderby de usar algum tipo de invólucro de SQL, por exemploORDER 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 Obrigado! Sua solução é a solução completa para esse problema. E aqui está o restante do código onde sua consulta é colocada. Vou publicá-lo como resposta para novos visitantes.
Gangesh
2

Encontrei esta solução combinando o código @bonger e /programming/18084199/wordpress-query-order-by-case-when

E isso funciona bem.

Função

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 da consulta

add_filter( 'posts_orderby', 'filter_case' );

$wp_query = new WP_Query($args);

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