12

I am working in MYSQL and need to extract user data to be pulled into a view. I will be using the data in an email client, so I cannot do this in the app layer.

The problem is that each data field for the user is contained in separate rows (this is how Wordpress sets up the data structure).

For example, wp_usermeta has multiple rows of data for each user like this:

user_id   meta_key       meta_data
   2      first_name     Jane
   2      last_name      Austin
   2      email          [email protected]
   3      first_name     Jack
   3      last_name      Palmer
   3      email          [email protected]

I need the data to be combined into one row, separate fields, like this:

user_id  first_name  last_name  email
2        Jane        Austin     [email protected]
3        Paul        Parker     [email protected]

I have searched around and cannot find this exact problem anywhere (I found a lot of concatenation, but that is not what I need).

1
  • 2
    Do you only care about firstName, lastName, and Email? Commented Nov 27, 2011 at 3:57

3 Answers 3

14

If these are the only columns you are concerned with, this will work for you:

SELECT um.user_id
   , fn.meta_data AS first_name
   , ln.meta_data AS last_name
   , e.meta_data AS email
FROM wp_userMeta AS um
LEFT JOIN wp_user_Meta AS fn ON um.user_id = fn.user_id
   AND fn.meta_key = 'first_name'
LEFT JOIN wp_user_Meta AS ln ON um.user_id = ln.user_id
   AND ln.meta_key = 'last_name'
LEFT JOIN wp_user_Meta AS e ON um.user_id = e.user_id
   AND e.meta_key = 'email'
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the quick response Adam. I tried to run the query, but all of the data fields are being populated by the column name, not the actual data. So all data for first_name is 'first_name', etc. SELECT um.user_id, fn.meta_key AS first_name, ln.meta_key AS last_name, e.meta_key AS email FROM wp_usermeta AS um LEFT JOIN wp_usermeta AS fn ON um.user_id = fn.user_id AND fn.meta_key = 'first_name' LEFT JOIN wp_usermeta AS ln ON um.user_id = ln.user_id AND ln.meta_key = 'last_name' LEFT JOIN wp_usermeta AS e ON um.user_id = e.user_id AND e.meta_key = 'email'
@katemerart Your SELECT is using meta_key instead of meta_data like my answer is suggesting. If you copy/paste my answer and run it you should get the results you desire.
Adam - that did it - Thanks! I had to add DISTINCT to keep from getting multiple rows of the same data, but I got it working. Thank you so much!!!
4

Here is an another solution that doesn't need additional join operations, instead, we make use of group by statement along with case statement.

select um.user_id,
       max(case when um.meta_key ='first_name' then um.meta_data end) AS first_name,  
       max(case when um.meta_key ='last_name' then um.meta_data end) AS last_name  ,
       max(case when um.meta_key ='email' then um.meta_data end) AS email
from wp_usermeta um 
group by user_id;

Note the max function is just for making them into one row, you can use min as well.

Check SQL Fiddler Demo here

Comments

0

The previous answer and comments give the correct solution. Here is the working query (in schema for WP 3.1) for copy and paste...

SELECT distinct u.id, u.user_email,
   fn.meta_value AS first_name,
   ln.meta_value AS last_name
FROM wp_users AS u
LEFT JOIN wp_usermeta AS fn ON u.id = fn.user_id
   AND fn.meta_key = 'first_name'
LEFT JOIN wp_usermeta AS ln ON u.id = ln.user_id
   AND ln.meta_key = 'last_name'

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.