Użycie Orderby i meta_value_num do uporządkowania liczb najpierw, a następnie łańcuchów

16

Mam listę produktów, z których każda zawiera cenę w polu niestandardowym zapisanym jako tekst, taki jak „2,50” lub „5,00”, i wyświetlam je na stronie za pomocą niestandardowego zapytania sortowanego według ceny:

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

Działa to dobrze w odniesieniu do cen, ale niektóre ceny to „POA” i chciałbym je pokazać na końcu, jednak powyższe zamówienia w taki sposób, aby „POA” był wyświetlany jako pierwszy.

Czy jest jakiś sposób, aby to zmienić, lub szybki hack, którego mógłbym użyć, aby posortować tablicę później i umieścić ceny „POA” na końcu?

Shaun
źródło
spróbuj zmienić 'orderby' => 'meta_value_num', na'orderby' => 'meta_value_num meta_value',
Bainternet,
Dzięki, ale to nie działa :(
Shaun,
Aha! Ale odwrotnie działa meta_value meta_value_num,! Dzięki! Czy chcesz napisać odpowiedź, abym mógł głosować?
Shaun
1
opublikowany jako odpowiedź dla osób, które nie czytają komentarzy.
Bainternet,
POA oznacza „cena za zapytanie” en.wikipedia.org/wiki/Price_on_application
sudip

Odpowiedzi:

23

OrderByArgument może wziąć więcej niż jeden parametr więc rozwiązaniem było zmianą:

'orderby' => 'meta_value_num',

do:

'orderby' => 'meta_value meta_value_num',
Bainternet
źródło
3
Po prostu sortuje się alfabetycznie, ponieważ drugim parametrem jest no-op, sortowanie według tego samego pola bez efektu. Aby to zrobić, aby liczby były sortowane numerycznie, a alfabet alfabetycznie, musisz użyć filtru, aby dostosować kolejność, używając jakiejś obudowy SQL, np.ORDER 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 Dziękujemy! Twoje rozwiązanie jest kompletnym rozwiązaniem tego problemu. A oto reszta kodu, w którym umieszczane jest zapytanie. Zamierzam opublikować to jako odpowiedź dla nowych gości.
Gangesh,
2

Znalazłem to rozwiązanie, łącząc kod przez @bonger i /programming/18084199/wordpress-query-order-by-case-when

I działa dobrze.

Funkcjonować

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

Przed zapytaniem

add_filter( 'posts_orderby', 'filter_case' );

$wp_query = new WP_Query($args);

remove_filter( 'posts_orderby', 'filter_case' );
Gangesh
źródło