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 <a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2b414a454e6b464e05484446">[email protected]</a> 3 first_name Jack 3 last_name Palmer 3 email <a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="3359525058735e561d505c5e">[email protected]</a>
I need the data to be combined into one row, separate fields, like this:
user_id first_name last_name email 2 Jane Austin <a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="8be1eae5eecbeee6eae2e7a5e8e4e6">[email protected]</a> 3 Paul Parker <a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b9d3d8dad2f9dcd4d8d0d597dad6d4">[email protected]</a>
I have searched around and cannot find this exact problem anywhere (I found a lot of concatenation, but that is not what I need).
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
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'
Method 2
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
Method 3
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'
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0