WP_Query orderby not working with meta_value_num and menu_order

I have made a custom post type (sidebar_element) which are shown on sidebar. On each sidebar element admin can choose where in sidebar should that element be shown, ie. ‘top’, ‘middle’ or ‘bottom’, and that the value is saved in meta field. Meta values for those alignments are 30, 20 and 10.

Now, if there are multiple sidebar elements with same alignment then they should be aligned by their menu_order value given.

Read More

This is how I’m trying to achieve all that, in my sidebar.php

$sidebarElems   = new WP_Query( array (
                        'post_type'         => 'sidebar_element',
                        'posts_per_page'    => -1,
                        'meta_key'          => 'sidebar_element_meta_alignment',
                        'orderby'           => 'meta_value_num menu_order',
                        'order'             => 'DESC' ) );

This however isn’t working. Elements get sorted first by meta_value_num ascending and then, correctly, by menu_order. If I delete the menu_order from orderby, meta_values gets properly ordered.

This thing is driving me crazy!

Please help. Thanks.

EDIT
Here’s the SQL Query generated, when var_dump($sidebarElems)

SELECT XXX_posts.* FROM XXX_posts
INNER JOIN XXX_postmeta ON (XXX_posts.ID = XXX_postmeta.post_id)
WHERE 1=1 AND XXX_posts.post_type = 'sidebar_element' AND (XXX_posts.post_status = 'publish') AND (XXX_postmeta.meta_key = 'sidebar_element_meta_alignment' )
GROUP BY XXX_posts.ID
ORDER BY XXX_postmeta.meta_value+0,XXX_posts.menu_order DESC

ANSWER
Found an answer, check below

Related posts

Leave a Reply

1 comment

  1. Found an answer to this.

    Somehow WordPress’ own orderby isn’t fully functional when trying to order by multiple values.

    I solved this by changing WP_Query to SQL Query, and including second DESC after _postmeta.meta_value+0

    SELECT XXX_posts.* FROM XXX_posts
    INNER JOIN XXX_postmeta ON (XXX_posts.ID = XXX_postmeta.post_id)
    WHERE 1=1 AND XXX_posts.post_type = 'sidebar_element' AND (XXX_posts.post_status = 'publish') AND (XXX_postmeta.meta_key = 'sidebar_element_meta_alignment' )
    GROUP BY XXX_posts.ID
    ORDER BY XXX_postmeta.meta_value+0 DESC,XXX_posts.menu_order DESC