Utilisation de Orderby et meta_value_num pour classer d'abord les nombres, puis les chaînes

16

J'ai une liste de produits, chacun avec un prix dans un champ personnalisé stocké sous forme de texte tel que "2,50" ou "5,00" et je les affiche sur la page avec une requête personnalisée qui trie par prix:

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

Cela fonctionne bien pour les prix, mais certains prix sont "POA" et je voudrais les montrer en dernier, cependant les commandes ci-dessus de telle sorte que "POA" soient affichées en premier.

Y a-t-il un moyen de modifier cela, ou un hack rapide que je pourrais utiliser pour trier le tableau par la suite et mettre les prix "POA" en dernier?

Shaun
la source
essayez de changer 'orderby' => 'meta_value_num', pour'orderby' => 'meta_value_num meta_value',
Bainternet
Merci mais cela ne fonctionne pas :(
Shaun
Ah! Mais l'inverse fonctionne meta_value meta_value_num,! Merci! Voulez-vous rédiger une réponse afin que je puisse la voter?
Shaun
1
publié comme réponse pour les personnes qui ne lisent pas les commentaires.
Bainternet
POA signifie "prix sur demande" en.wikipedia.org/wiki/Price_on_application
sudip

Réponses:

23

L' OrderByargument peut prendre plus d'un paramètre, la solution a donc été de changer:

'orderby' => 'meta_value_num',

à:

'orderby' => 'meta_value meta_value_num',
Bainternet
la source
3
Cela trie simplement par ordre alphabétique, car le deuxième paramètre est un no-op, triant sur le même champ sans effet. Pour ce faire, afin que les nombres soient triés numériquement et les alphas par ordre alphabétique, vous devez utiliser un filtre pour personnaliser l'ordre en utilisant une sorte de casse SQL, par exempleORDER 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 Merci! Votre solution est une solution complète à ce problème. Et voici le reste du code où votre requête est placée. Je vais le poster comme réponse pour les nouveaux visiteurs.
Gangesh
2

J'ai trouvé cette solution en combinant le code de @bonger et /programming/18084199/wordpress-query-order-by-case-when

Et ça marche bien.

Une fonction

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

Avant la requête

add_filter( 'posts_orderby', 'filter_case' );

$wp_query = new WP_Query($args);

remove_filter( 'posts_orderby', 'filter_case' );
Gangesh
la source