web-dev-qa-db-ja.com

1つのmeta_keyでクエリし、別のソート(おそらくNULL値)

1つのメタキーでクエリしたいのですが、存在してもしなくてもよい別のキーでソートし、 その後 投稿日順

したがって、最終結果は次のようになります。

メタキーA /日付1
メタキーA /日付2
メタキーB /日付1
メタキーなし/日付1
メタキーなし/日付2

次のようなクエリ引数は投稿を返しません。

$customer_orders = get_posts( array(
    'numberposts' => $order_count,
    'meta_query' => array(
        array(
            'key'     => '_customer_user',
            'value'   => get_current_user_id(),
            'compare' => '=',
        ),
        array(
            'key'     => '_dealer_number',
            'compare' => 'EXISTS',
        ),
        array(
            'key'     => '_dealer_number',
            'compare' => 'NOT EXISTS',
        ),
        'relation' => 'AND'
    ),
    'orderby'    => 'meta_value date',
    'order'      => 'ASC'
) );

これはWP_Query引数で可能ですか、それともposts_orderbyをフィルタする必要がありますか?もしそうなら、私は何を使うことができますか?

3
helgatheviking

フィルタを使わずにそれを実行する方法はないと思います。 posts_clausesを使えば、次のことができます。

function wpse163696_posts_clauses( $pieces, $query ) {
    if ( $query->get( 'orderby' ) != 'dealer_date' ) {
        return $pieces;
    }
    global $wpdb;

    $order = $query->get( 'order' );
    $pieces[ 'join' ] .= $wpdb->prepare(
        ' LEFT JOIN ' . $wpdb->postmeta . ' dealer_pm ON dealer_pm.post_id = ' . $wpdb->posts . '.ID AND dealer_pm.meta_key = %s'
        , '_dealer_number' );
    $pieces[ 'orderby' ] = 'ISNULL(MAX(dealer_pm.meta_value)) ' . $order . ', MAX(dealer_pm.meta_value) ' . $order  . ', ' . $wpdb->posts . '.post_date ' . $order;
    return $pieces;
}

それからあなたの質問は次のようになります。

add_filter( 'posts_clauses', 'wpse163696_posts_clauses', 10, 2 );
$customer_orders = get_posts( array(
    'numberposts' => $order_count,
    'meta_query' => array(
        array(
            'key'     => '_customer_user',
            'value'   => get_current_user_id(),
            'compare' => '=',
        ),
    ),
    'orderby'    => 'dealer_date',
    'order'      => 'ASC',
    'suppress_filters' => false,
) );
remove_filter( 'posts_clauses', 'wpse163696_posts_clauses', 10 );
3
bonger

あなたはそこにいくつかの誤りがあります、と私は思います。

1) 'numberposts'のようなパラメータはありません。おそらく 'posts_per_page'という意味でしょうか。それはあなたが表示する投稿の数を決めるために使うべきものです。

2)メタ値で並べ替える場合、正しい構文は次のようになります。

'orderby' => 'meta_value',
'meta_key' => 'key_name', 

Key_nameは、そのmeta_valueをオーダーに使用するカスタムフィールドです。

したがって、あなたの質問に基づいて、あなたの質問はこのように見えるかもしれません:

$customer_orders = get_posts( 
                        array(
                            'posts_per_page' => $order_count,
                            'no_found_rows' => true,
                            'meta_query' => array(
                                                array(
                                                    'key'     => '_customer_user',
                                                    'value'   => get_current_user_id(),
                                                    'compare' => '=',
                                                ),
                                                array(
                                                    'key'     => '_dealer_number',
                                                    'compare' => 'EXISTS',
                                                ),
                                                array(
                                                    'key'     => '_dealer_number',
                                                    'compare' => 'NOT EXISTS',
                                                ),
                                                'relation' => 'AND'
                                            ),
                            'orderby'    => 'meta_value',
                            'meta_key'   => 'date',
                            'order'      => 'ASC'
                        ) 
                    );

( 'no_found_rows'を追加したことに注意してください。あなたが何件の投稿をクエリしようとしていて、ページネーションを必要としないのか知っていれば、この追加はクエリを大幅にスピードアップします)。

1
Biranit Goren