• Some of my posts will have two meta_keys set called ‘meta_1’ and ‘meta_2’ while most will only ever have ‘meta_1’.

    ‘meta_1’ will always contain a number greater than 0
    ‘meta_2’ will either be set with a number 1 or will not be set

    I’m trying to get all my posts from the database queried in such a way that posts with ‘meta_2’ are shown first with all posts ordered by ‘meta_1’.

    What I have so far is getting posts ordered by ‘meta_1’ in either ascending order or descending order or posts ordered by ‘meta_2’ being set or not set.

    add_action( 'pre_get_posts', 'get_posts' );
    function get_posts( $query ) {
      if( !is_admin() && $query->is_main_query() ) :
        $query->set( 'posts_per_page', '9' );
    
        switch ( $_GET['sortType'] ) :
          case 'ASC':
            $query->set( 'orderby', array( 'meta_value_num' => 'ASC' ) );
            $query->set( 'meta_key', 'meta_1' );
            break;
          case 'DESC':
            $query->set( 'orderby', array( 'meta_value_num' => 'DESC' ) );
            $query->set( 'meta_key', 'meta_1' );
            break;
          default:
            $query->set( 'meta_key', 'meta_2' );
            $query->set( 'orderby', array( 'meta_value_num' => 'DESC', 'title' => 'ASC' ) );
            $query->set( 'meta_query', array( 'relation' => 'OR',
              array( 'key' => 'meta_2', 'value' => '1', 'compare' => '=' ),
              array( 'key' => 'meta_2', 'compare' => 'NOT EXISTS' )
            ) );
        endswitch;
      endif;
    }

    How can I show the posts with meta_key ‘meta_2’ on the top of the query results and have all posts ordered by meta_key ‘meta_1’?

    Say I have 4 posts (p.ID 1, 2, 3, 4)

    • Post 1: ‘meta_1’ = 9
    • Post 2: ‘meta_1’ = 7, ‘meta_2’ = 1
    • Post 3: ‘meta_1’ = 3
    • Post 4: ‘meta_1’ = 2, ‘meta_2’ = 1

    Posts should be returned as:

    • Post 4
    • Post 2
    • Post 3
    • Post 1
Viewing 2 replies - 1 through 2 (of 2 total)
  • Because some of the posts will not have meta_2 I don’t think you’ll be able to use a meta_query. You might have better luck performing a direct SQL statement using $wpdb to retrieve the post IDs in the order you want and then passing those to post__in combined with the ‘post__in’ option for orderby.

    Thread Starter philiprabbett

    (@philiprabbett)

    Well I’m able to get all posts containing ‘meta_2’ showing first followed by all those without…

    $query->set( 'meta_key', 'meta_2' );
    $query->set( 'orderby', array( 'meta_value_num' => 'DESC' ) );
    $query->set( 'meta_query', array( 'relation' => 'OR',
        array( 'key' => 'meta_2', 'value' => '1', 'compare' => '=' ),
        array( 'key' => 'meta_2', 'compare' => 'NOT EXISTS' )
    ) );
Viewing 2 replies - 1 through 2 (of 2 total)
  • The topic ‘Query posts order by multiple postmeta’ is closed to new replies.