如何对WP_QUERY进行排序以分组结果?

时间:2015-07-29 作者:Keith Donegan

我在WooCommerce有一个产品列表,标题如下:

Please note: The "groups" are just for myself, they are not categories etc. All products are the same type of product, just two types of products have different codes (Z and UK)

"Group 1" - 唯一编号

5000等"Group 2" - 以a开头的唯一数字Z

Z5000等"Group 3" - 以开头的唯一数字UK

UK5000、UK4999、UK4998、UK4997、UK4996、UK4996等,显然默认情况下,WordPress按日期排序,所以在产品的归档页面上,它们看起来是这样的:

UK4020等我想要的(但似乎无法用我的Google fu找到任何答案)是定制我的产品,如下所示:

  • Unique numbers, in descending order
  • Unique numbers that begin with Z, in descending order
  • Unique numbers that begin with UK, in descending order
。。。所以我的产品是这样的:

5000、4999、Z5000、Z4999、UK5000、UK4999、UK4999等,希望以上有意义!

2 个回复
SO网友:s_ha_dum

如果您的命名系统是一致的,那么只需按帖子名称排序即可:

$args = array(
    \'orderby\' => \'title\', 
    \'order\' => \'ASC\',
);
$q = new WP_Query($args);
var_dump($q->request);
var_dump(wp_list_pluck($q->posts,\'post_title\'));
或者,作为pre_get_posts 过滤器(假设主查询是我们要更改的):

add_action(
  \'pre_get_posts\',
  function ($qry) {
    if ($qry->is_main_query()) {
      $qry->set(\'orderby\',\'title\');
    }
  }
);
我认为这是一个脆弱的解决方案。一个更复杂但更可靠的方法是为您的ID保存自定义元,并按该自定义元排序。

如果您将数据保存为自定义元,请改用以下参数:

$args = array(
    \'meta_key\' => \'SKU\', // maybe sku; or whatever your KEY is
    \'orderby\' => \'meta_value\',
    \'order\' => \'ASC\',
);

SO网友:bonger

我想你需要一个过滤器posts_orderby 为此,请执行以下操作:

add_filter( \'posts_orderby\', function ( $orderby, $query ) {
    if ( $query->get( \'orderby\' ) == \'zuk\' ) {
        global $wpdb;
        //$field = $wpdb->posts . \'.post_title\';
        $field = $wpdb->postmeta . \'.meta_value\';
        $order = $query->get( \'order\' );
        $orderby = $wpdb->prepare(
            \'CASE\'
            . \' WHEN LEFT(\' . $field . \', 1) = %s THEN CONCAT(%s, LPAD(SUBSTR(\' . $field . \', 2), LENGTH(~0), %s))\'
            . \' WHEN LEFT(\' . $field . \', 1) = %s THEN CONCAT(%s, LPAD(SUBSTR(\' . $field . \', 3), LENGTH(~0), %s))\'
            . \' ELSE LPAD(\' . $field . \', LENGTH(~0), %s)\'
            . \' END \' . $order
            , \'Z\', \'A\', \'0\', \'U\', \'B\', \'0\', \'0\'
        );
    }
    return $orderby;
}, 10, 2 );

$args = array(
    \'meta_key\' => \'SKU\',
    \'orderby\' => \'zuk\',
    \'order\' => \'ASC\',
);
$query = new WP_Query( $args );
(如果数据的编号始终为5位数,则可以根据长度进行排序:

add_filter( \'posts_orderby\', function ( $orderby, $query ) {
    if ( $query->get( \'orderby\' ) == \'zuk\' ) {
        global $wpdb;
        //$field = $wpdb->posts . \'.post_title\';
        $field = $wpdb->postmeta . \'.meta_value\';
        $order = $query->get( \'order\' );
        $orderby = \'LENGTH(\' . $field . \') \' . $order . \', \' . $field . \' \' . $order;
    }
    return $orderby;
}, 10, 2 );
但这显然要脆弱得多。)

结束

相关推荐

Archive not sorting correctly

我有一个名为“cif事件”的自定义帖子类型,我想按wpcf开始时间中的值进行排序。我在函数中添加了以下内容。php:add_filter(\'pre_get_posts\', \'set_order_for_archives\'); function set_order_for_archives($q) { if ($q->is_post_type_archive(\'cif-groups\')) { $q->set(\'orderby\', \'