1

I have a custom user query, which should order users by a custom meta field staff_profile_position. Users, who don't have a staff_profile_position are not fetched with this query:

$args = array(
    'role'  => 'my_staff_role',
    'fields' => 'all',
    'meta_key' => 'staff_profile_position',
    'meta_query' => array(
        'relation' => 'OR',
        array(
            'key'     => 'staff_profile_position',
            'compare' => 'EXISTS',
        ),
        array(
            'key'           => 'staff_profile_position',
            'compare'   => 'NOT EXISTS',
        ),
    ),
    'orderby' => array(
        'meta_value_num' => 'ASC',
    ),
);

How can I get all users ordered by staff_profile_position, if they have, followed by all the others?

The query above follows this answer. But still doesn't work and only fetches users that have this meta field.

1

The reason you're only getting those users that have that meta_key is because you're include 'meta_key' => '...' in $args. That limits results to those that have that key, regardless of any clauses you may have in a meta_query. This applies to WP_Query, WP_User_Query and WP_Comment_Query.

Starting in WP 4.2, you can "name" the clauses in a meta_query and then use those "names" in the orderby clause, see Query improvements in WP 4.2: ‘orderby’ and ‘meta_query’. Unfortunately, the code reference and codex entries for WP_Query and WP_User_Query haven't been updated to reflect this, altho WP_Meta_Query does cover it.

So, you can ALMOST get what you're after with the following:

$args = array (
    'role'  => 'my_staff_role',
    'fields' => 'all',
    'meta_query' => array (
        'relation' => 'OR',
        'exists' => array (
            'key' => 'staff_profile_position',
            'compare' => 'EXISTS',
//          'type' => 'NUMERIC',
            ),
        'not_exists' => array (
            'key'     => 'staff_profile_position',
            'compare'   => 'NOT EXISTS',
            ),
        ),
    'orderby' => 'exists not_exists',
    ) ;

Note: To mimic 'orderby' => 'meta_value_num' (as you have in your question) you would have to include 'type' => 'NUMERIC' in the meta_query clauses. However, that causes all of users without to sort to the top, instead of the bottom (which is why I have it commented out above).

Thus, if you can live with having those users with your meta_key to be ordered by that key treated as a string, rather than a number, then the above will do.

If you can't, then you'll have to do 2 separate queries (one for those users with the meta_key, ordered numerically by that key, and one for those users without the meta_key) and merge the results of those 2 queries.

  • Oh good to know. I've read through the Query Improvements docs but didn't find out about this "naming" option. Cheers! – Bunjip Mar 23 '17 at 17:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.