Использование Orderby и meta_value_num, чтобы сначала упорядочить числа, а затем строки

16

У меня есть список продуктов, каждый с ценой в настраиваемом поле, хранящийся в виде текста, такого как «2,50» или «5,00», и я отображаю их на странице с помощью пользовательского запроса, который сортируется по цене:

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

Это хорошо работает для цен, но некоторые цены "POA", и я хотел бы показать их в последний раз, однако вышеупомянутые заказы таким образом, что "POA" отображается первым.

Есть ли способ изменить это, или быстрый взлом, который я мог бы использовать, чтобы потом отсортировать массив и поставить последние цены «POA»?

Shaun
источник
попробуйте перейти 'orderby' => 'meta_value_num', на'orderby' => 'meta_value_num meta_value',
Bainternet
Спасибо, но это не работает :(
Шон
Ага! Но наоборот работает meta_value meta_value_num! Благодарность! Вы хотите написать ответ, чтобы я мог проголосовать за него?
Шон
1
опубликовано как ответ для людей, которые не читают комментарии.
Bainternet
POA означает «цена за запрос» en.wikipedia.org/wiki/Price_on_application
sudip

Ответы:

23

OrderByАргумент может принимать более одного параметра , поэтому решение было изменения:

'orderby' => 'meta_value_num',

чтобы:

'orderby' => 'meta_value meta_value_num',
Bainternet
источник
3
Это просто сортировка в алфавитном порядке, так как второй параметр не используется, сортировка по тому же полю безрезультатно. Чтобы сделать так, чтобы числа сортировались по номерам и по алфавиту в алфавитном порядке, вам нужно было бы использовать фильтр для настройки порядка, чтобы использовать какой-то тип SQL-оболочки, например,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 Спасибо! Ваше решение является полным решением этой проблемы. А вот и остальная часть кода, где размещен ваш запрос. Я собираюсь опубликовать это как ответ для новых посетителей.
Гангеш
2

Я нашел это решение, объединив код @bonger и /programming/18084199/wordpress-query-order-by-case-when

И это хорошо работает.

функция

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

Перед запросом

add_filter( 'posts_orderby', 'filter_case' );

$wp_query = new WP_Query($args);

remove_filter( 'posts_orderby', 'filter_case' );
Gangesh
источник