I have a case where, if I had written the DB and queries myself, I would just do something like SELECT name, firstname, email FROM users WHERE .... Returning me a list/collection/array, I mean, not necessarily a single user.

But I learned that to get name and firstname in WordPress, you first need to get the IDs of some users, then use something like this $targetUsers = get_users(['include' => wp_list_pluck($targetUsersIDs,'ID')]);

This means that I get a collection of complete user objects, which is potentially a lot of data for nothing.

For now, the best thing I come up with would be to run this query:

SELECT u.ID, u.user_email, um.meta_key, um.meta_value FROM wp_users u JOIN wp_usermeta um ON u.ID = um.user_id
WHERE um.meta_key = 'last_name' OR um.meta_key = 'first_name'
GROUP BY u.ID, u.user_email, um.meta_key, um.meta_key

and then loop over of it to build my own objects.

Or maybe there is something to do with some nested query...

Please note that the question is not about selecting specific fields from the user table but from the user meta table!

1 Answer 1


I think you should stick to WP_User_Query. There you can simply specify the fields you want to use to select certain users. Also meta fields.

WP_User_Query is a class, defined in wp-includes/user.php, that allows querying WordPress database tables wp_users and wp_usermeta.

But yes(!), this will not return you user meta values. Even when setting 'fields' => 'all_with_meta'.

all_with_meta currently returns the same fields as all which does not include user fields stored in wp_usermeta. You must create a second query to get the user meta fields by ID or use the __get PHP magic method to get the values of these fields.

That said, my conclusion would be to indeed use meta_query in a WP_User_Query to select users by certain meta values and use that result to retrieve additional meta data by calling for example get_user_meta($user->ID, 'meta_key', TRUE).

$user_query = new WP_User_Query([
  'role'       => 'editor', 
  'meta_query' => [
      'key'     => 'meta_key',
      'compare' => 'EXISTS', // Use 'NOT EXISTS' for non-existance of this key.

$editors = $user_query->get_results();

foreach ($editors as $editor) {
  $first_name = $editor->display_name;
  $meta_value = get_user_meta($editor->ID, 'meta_key', TRUE);
  // ...

That's one hundred times more readable and maintainable than a custom database query, in my opinion.

And regarding performance, maybe check out this related answer on the same topic just for post meta data: Can WP_Query return post meta in a single request? which links you to: Custom post meta field effect on the performance on the post.

  • I'm not convinced regarding the performance thing ... The test says 0.00195 seconds/post. So if I ever have like 100 users that's already nearly 0,2 seconds ... 1000 users, that's almost 2 seconds ... which is gigantic. There are also soo many metadata to load in memory or cache for nothing ...
    – TTT
    Commented Apr 11, 2019 at 13:18
  • @TTT – Premature optimization is the root of all evil. ^^
    – leymannx
    Commented Apr 11, 2019 at 13:32
  • That's why I won't do too much optimisation right away ... Maybe I should wrap things in a way that if I someday have to optimise it it will be clearer in a distinct method. But I've seen developer pushing this statement so far in the wrong direction that it recursively became the root of evil iself ...
    – TTT
    Commented Apr 11, 2019 at 13:44

Your Answer

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

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