Reputation: 5249
I have a two mysql tables that I want to merge together in one query. It's best described by an example:
table: users
| user_id | username |
| 1 | jason |
| 2 | justin |
table: user_data
| user_id | key | data |
| 1 | email | [email protected] |
| 1 | phone | 555-123-4567 |
| 2 | email | [email protected]|
| 2 | phone | 555-765-4321 |
query results:
| user_id | username | email | phone |
| 1 | jason | [email protected] | 555-123-4567 |
| 2 | justin | [email protected] | 555-765-4321 |
You can assume that the keys are pretty uniform among all of the users (ie. all users have an email and phone). My first thought would be to do something like this but I'm curious if there is a better way:
SELECT *,e.data as email,p.data as phone FROM users u
LEFT JOIN user_data AS e ON e.user_id=u.user_id AND `key`='email'
LEFT JOIN user_data AS p ON p.user_id=u.user_id AND `key`='phone';
Upvotes: 0
Views: 452
Reputation: 31991
I agree with @Mark Bayers.
However, if you sticking to your design, you should consider this: is it possible that one user could have more than one email? or more than one phone? If that is the case, then you will get all combinations of phone and email per user.
If you just want one row for each user, with all the data in the respective fields, you could try this:
SELECT users.id, users.username
, GROUP_CONCAT(IF(user_data.key = 'email', user_data.data, NULL)) emails
, GROUP_CONCAT(IF(user_data.key = 'phone', user_data.data, NULL)) phones
FROM users
INNER JOIN user_data
ON users.id = user_data.user_id
GROUP BY users.id
Upvotes: 0
Reputation: 839114
all users have an email and phone
Then why not add columns for them in the original table?
table: users
| user_id | username | email | phone |
| 1 | jason | .... | .... |
| 2 | justin | .... | .... |
It will make querying much easier and faster.
The design you are using is called Entity-attribute-value (EAV) and is generally useful when there are many attributes but they are sparsely populated.
Assuming you can't or don't want to change the table design, the only change I'd make to your query is to not use SELECT *
. List the columns explicitly.
Upvotes: 2