How to order by multiple meta keys?
Asked Answered
D

5

24

I’m using a custom loop to display my events on a page, I get it fine ordering by the event start date using the below:

$args = array( 
    'post_type' => 'event',
    'order' => 'ASC',
    'orderby' => 'meta_value',
    'meta_key' => '_event_start_date');
$loop = new WP_Query( $args );

But the meta_key option only allows one value. How to use two values (_event_start_date and _event_start_time)?

Donough answered 19/7, 2013 at 11:45 Comment(1)
I am also looking for that, and i'm afraid only WP4.0 allows this. I tried all possible configurations of Query parameters without success on 3.9...Draughts
F
33

This is something that WordPress added support for in 4.2: https://make.wordpress.org/core/2015/03/30/query-improvements-in-wp-4-2-orderby-and-meta_query/

Please note: It is not so obvious, but for ordering with multiple meta keys you have to give each meta_query a name and then use these names in the orderby.

In your case you'll probably want to do something like this:

$args = array(
    'post_type'  => 'event',
    'meta_query' => array(
        'relation' => 'AND',
        'event_start_date_clause' => array(
            'key'     => '_event_start_date',
            'compare' => 'EXISTS',
        ),
        'event_start_time_clause' => array(
            'key'     => '_event_start_time',
            'compare' => 'EXISTS',
        ), 
    ),
    'orderby' => array(
        'event_start_date_clause' => 'ASC',
        'event_start_time_clause' => 'ASC',
    ),
);

$loop = new WP_Query( $args );
Finsteraarhorn answered 20/2, 2016 at 0:50 Comment(1)
Was in similar situation where I've opted for this solution and worked perfectly :). Thanks man it made my day..Cording
E
1

You have to use meta_query at add your meta keys as everyone said, but also you have to customize order by function.

$args = array(
    'post_type' => 'event',
    'meta_key' => '_event_start_date',
    'meta_query' => array(
        array('key' => '_event_start_date'),
        array('key' => '_event_start_time')
    ),
);

add_filter('posts_orderby','customorderby');
$loop = new WP_Query( $args );
remove_filter('posts_orderby','customorderby');

And put this on your functions.php

function customorderby($orderby) {
    return 'mt1.meta_value ASC, mt2.meta_value ASC';
}

You can read more at http://dotnordic.se/sorting-wordpress-posts-by-several-numeric-custom-fields/

Encamp answered 23/11, 2015 at 13:4 Comment(0)
A
0

You can order on one key, of multiple. Like so:

        $events = get_posts(array(
           'post_type' => 'my_event',
           'post_status' => 'publish',
           'meta_query' => array(
               array(
                   'key'    =>  'my_event_type',
                   'value'  =>  'aGoodOne'
               ),

               array(
                   'key'    =>  'my_event_start',
                   'value'  =>  time(), // in this case, only grabbing upcoming events
                   'compare'=>  '>',
                   'type'   =>  'NUMERIC' //  assuming value is unix timestamp
               )
           ),
           'meta_key'   =>  'my_event_start', // we're sorting on the start time key
           'orderby'    =>  'meta_value_num', // it's a numeric value
           'order'      =>  'ASC' // in chrono order
        ));

The key here is that meta_key specifies which key we're ordering by, of the ones we use to grab our records with meta_query.

Andreas answered 12/11, 2013 at 23:18 Comment(1)
As useful as this is, it doesn't answer the original question. This answers "If I query by multiple meta keys, how do I order by a single meta key?" what was asked was "I am pulling in posts, and need to order them using multiple meta keys".Tosch
D
-1

  add_action( 'pre_get_posts', 'pre_get_posts_programpunkter' );

function pre_get_posts_programpunkter( $query ) {
	
	if( !is_admin()  && is_post_type_archive( 'programpunkt' ) && $query->is_main_query() ) {
		
		$query->set( 'orderby', 'meta_value' );
		$query->set( 'meta_key', 'event-date' );
			
		$query->set( 'meta_query', array(
			'relation' => 'AND', 
				array( 'key' => 'event-date', 'compare' => 'EXISTS' ), 
				array( 'key' => 'event-start', 'compare' => 'EXISTS' ) 
			) 
		);
			
		$query->set( 'order', 'ASC' );
				
	}
}

add_filter('posts_orderby', 'programpunkter_orderby');

function programpunkter_orderby( $orderby ) {
	
	if( get_queried_object()->query_var === 'programpunkt' )  {
		
		global $wpdb;		
		$orderby = str_replace( $wpdb->prefix.'postmeta.meta_value', 'mt1.meta_value, mt2.meta_value', $orderby );	
		
	}	
	return $orderby;
}
Debtor answered 13/2, 2015 at 19:36 Comment(1)
While these links may answer the question, it is better to include the essential parts of the answer here and provide the links for reference. Link-only answers can become invalid if the linked pages change.Intramuscular
R
-2

From WP_Query documentation, use meta_query and fill up with an array of meta key/values:

$args = array(
    'post_type' => 'product',
    'meta_query' => array(
        array(
            'key' => 'color',
            'value' => 'blue',
            'compare' => 'NOT LIKE'
        ),
        array(
            'key' => 'price',
            'value' => array( 20, 100 ),
            'type' => 'numeric',
            'compare' => 'BETWEEN'
        )
    )
);
$query = new WP_Query( $args );
Rowdyish answered 19/7, 2013 at 12:24 Comment(3)
But that doesn't help with ordering does it?Donough
Not quite sure, check this search query.Rowdyish
My answer below clarifies this, with regards to ordering with multiple meta key queries.Andreas

© 2022 - 2024 — McMap. All rights reserved.