0

Table 1 - users example

ID   usr_login  user_email        display_name
1    john       john@gmail.com    John Jones    
2    steve      steve@att.com     Steve Jobs    
3    tom        tom@verizon.net   Tom Thumb

Table 2 - usermeta

umeta_id  user_id   meta_key    meta_value    
1         1         phone       8005551212    
2         1         email       john@gmail.com    
3         1         b_date      12/25    
20        2         phone       2025554567    
21        2         email       steve@att.com    
22        2         b_date      11/01    
40        3         phone       9095559876    
41        3         email       tom@verizon.net    
42        3         b_date      01/30

I am trying to display the fields on a webpage in this format

User1-DisplayName     User1-eMailAddress     User1-Phone     User1-Bdate
User2-DisplayName     User2-eMailAddress     User2-Phone     User2-Bdate
User3-DisplayName     User2-eMailAddress     User3-Phone     User3-Bdate

I can get data to display from each of the tables. But, I have not been able to get data to show from both tables together. I know enough to know that I should use a join, but can seem to get the select statement correct.

Thanks in advance, Kevin

Nick
  • 138,499
  • 22
  • 57
  • 95
KevinW
  • 3
  • 2

1 Answers1

1

Since you say you can already get data from the tables individually, I'm assuming all you need is the appropriate SQL query. To get the data you want, you need to join the users table to the usermeta table twice, once to get the phone value and once to get the b_date value. In each case the join condition is on the user_id value and the appropriate meta_key value:

SELECT u.display_name,
       u.user_email,
       p.meta_value AS phone,
       b.meta_value AS bdate
FROM users u
JOIN usermeta p ON p.user_id = u.ID AND p.meta_key = 'phone'
JOIN usermeta b ON b.user_id = u.ID AND b.meta_key = 'b_date'
ORDER BY u.ID

Output:

display_name    user_email          phone       bdate
John Jones      john@gmail.com      8005551212  12/25
Steve Jobs      steve@att.com       2025554567  11/01
Tom Thumb       tom@verizon.net     9095559876  01/30

Note I've assumed you get the user_email value from the users table; if you want to get that from usermeta as well, you would join a third time:

SELECT u.display_name,
       e.meta_value AS user_email,
       p.meta_value AS phone,
       b.meta_value AS bdate
FROM users u
JOIN usermeta e ON e.user_id = u.ID AND e.meta_key = 'email'
JOIN usermeta p ON p.user_id = u.ID AND p.meta_key = 'phone'
JOIN usermeta b ON b.user_id = u.ID AND b.meta_key = 'b_date'
ORDER BY u.ID

The output is the same for this query.

Demo on db-fiddle

Note also that I've assumed you have email, phone and b_date records in the usermeta table for each user. If you don't, you will need to change the JOINs into LEFT JOINs, and use a COALESCE to convert any resultant NULL values into empty strings e.g.

COALESCE(p.meta_value, '') AS phone

For example:

SELECT u.display_name,
       COALESCE(e.meta_value, '') AS user_email,
       COALESCE(p.meta_value, '') AS phone,
       COALESCE(b.meta_value, '') AS bdate
FROM users u
LEFT JOIN usermeta e ON e.user_id = u.ID AND e.meta_key = 'email'
LEFT JOIN usermeta p ON p.user_id = u.ID AND p.meta_key = 'phone'
LEFT JOIN usermeta b ON b.user_id = u.ID AND b.meta_key = 'b_date'
ORDER BY u.ID

Demo on db-fiddle

Nick
  • 138,499
  • 22
  • 57
  • 95
  • Nick, thank you for your quick response! Not sure why that code returned only 6 records when I ran the query on the database. It returned records 3, 4, 8, 15, 17, 23, 29 from the users table. All records returned have user_email. Five of the records returned have phone & b_date. I tried to get it to return ID from the users table, for troubleshooting, with no success. I also tried to adapt this code to PHP, since the end goal is to display this on a web page from a php file. – KevinW Nov 06 '20 at 18:44
  • I tried eliminating the lines for b_date and it returned 28 lines. Still missing the last 3 users records entered. I eliminated the phone lines and it returned the same 28 records. I did get it to display the ID column from the users table. – KevinW Nov 06 '20 at 18:53
  • I did find that the only users_id that have the b-date field are those 6 that are returned. How do you get it to return all records from users and show the columns from usermeta whether they have the key in meta_key for the user_id? – KevinW Nov 06 '20 at 19:02
  • @KevinW I've assumed you have `email`, `phone` and `b_date` records in the `usermeta` table for each user. If you don't, you will need to change the `JOIN`s into `LEFT JOIN`s, and use a `COALESCE` to convert the resultant `NULL` values into empty strings e.g. `COALESCE(p.meta_value, '') AS phone`. See for example https://www.db-fiddle.com/f/qJourHVhcofbVaWEk4DCEP/3 – Nick Nov 06 '20 at 20:23
  • @KevinW I've updated the answer to reflect my prior comment – Nick Nov 06 '20 at 20:33
  • Nick, THANK YOU! That pulled the records exactly how I wanted to in the DB Admin Query. Any suggestions on how to get those results in a php file? – KevinW Nov 06 '20 at 21:06
  • @KevinW good to hear. Have you not written any PHP to get the data from the other tables? – Nick Nov 06 '20 at 21:08
  • Nick, I am a total beginner at coding. Been on the server support side for over 20 years, this is not my first time coding (I have a PHP file that pulls data from my home temperature database and displays it on a web page on my nas). In php I can get data out of both tables in separate PHP files. But I am not having success getting data out of both tables at the same time. I tried copying and pasting some/all of your code and either get a 500 error or get 0 results. I want my wife to be able to pull the user data that she needs by herself and I don't want here anywhere near SQL admin... – KevinW Nov 06 '20 at 21:54
  • I suggest you start a new question, including the PHP code you are using and explaining the issues you are having, as that is unrelated to the query code above and would otherwise make this question too broad. When you've posted it, ping me in a comment here and I will take a look at it. If you already have code working to read from the separate tables, it probably won't be too difficult to get working for this. – Nick Nov 06 '20 at 22:14
  • Worked on it for several hours with no success, so I took your recommendation and asked a new question. https://stackoverflow.com/questions/64732428/convert-sql-query-with-coalesce-and-left-join-to-php – KevinW Nov 07 '20 at 21:08
  • Nick, I don't know why my question got closed. I deleted that question and asked another one, including the PHP code that I have tried. https://stackoverflow.com/questions/64740320/convert-sql-query-with-coalesce-and-left-join-to-php – KevinW Nov 08 '20 at 16:20
  • @KevinW I guess you saw the comment that explains the issue with your code; you need to append to the `$sql` variable on each line, you are currently overwriting it. – Nick Nov 08 '20 at 22:44