I'm using pre_get_posts to alter my main query and attach a meta query to it. This is on a woocommerce products archive page (...not sure if that would make a difference).

function has_upcoming_date( $query ) {
    if( ! is_admin() && $query->is_main_query() && $query->query_vars['product_cat'] == 'wine-classes' ) {
        $meta_query = array(
        $query->set('meta_query', $meta_query);
        $query->set('posts_per_page', -1);
        $query->set('meta_key', 'wfd_upcoming_booking_date');
        $query->set('orderby', 'meta_value_num');
        $query->set('order', 'ASC');

add_action( 'pre_get_posts', 'has_upcoming_date', 10000000 );

The meta query works well, and filters the posts correctly. The orderby => meta_value seems to work as well. But the order isn't changed to ascending.

This is the sql request I can see using Query Monitor:

SELECT wp_posts.*
FROM wp_posts 
INNER JOIN wp_term_relationships
ON (wp_posts.ID = wp_term_relationships.object_id)
INNER JOIN wp_postmeta
ON ( wp_posts.ID = wp_postmeta.post_id ) 
INNER JOIN wp_postmeta AS mt1
ON ( wp_posts.ID = mt1.post_id )
WHERE 1=1 
AND ( wp_term_relationships.term_taxonomy_id IN (110) )
AND ( wp_postmeta.meta_key = 'wfd_upcoming_booking_date' 
AND ( ( mt1.meta_key = 'wfd_upcoming_booking_date'
AND CAST(mt1.meta_value AS SIGNED) > '0' ) ) )
AND wp_posts.post_type = 'product'
AND (wp_posts.post_status = 'publish'
OR wp_posts.post_status = 'acf-disabled'
OR wp_posts.post_status = 'private')
GROUP BY wp_posts.ID
ORDER BY wp_postmeta.meta_value+0 DESC, wp_posts.post_date DESC

Can anyone tell why this wouldn't be working or where else I should look to diagnose?

  • meta_query should be an array of arrays - See Codex. Maybe trying 'orderby', 'meta_value_num'.
    – Howdy_McGee
    Commented Jun 27, 2016 at 15:06
  • not sure if casting as CHAR then ordering numerically would be an issue. are you literally saving the string NULL as a value?
    – Milo
    Commented Jun 27, 2016 at 15:09
  • @Milo, no, it was saving the null value. But now I've updated it to save the string 0 and compare => ">". Doesn't seem to make a difference.
    – rob-gordon
    Commented Jun 27, 2016 at 15:26
  • @Howdy_McGee I changed the meta query to an array of arrays, and it still filters correctly, but the order => "ASC" still isn't respected - using meta_value or meta_value_num
    – rob-gordon
    Commented Jun 27, 2016 at 15:28
  • have a look at the WP_Query codex page for the EXISTS operator, and the array syntax for multiple orderby conditions.
    – Milo
    Commented Jun 27, 2016 at 15:46


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.