jasonlfunk
jasonlfunk

Reputation: 5249

Merge two tables in MySQL

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

Answers (2)

Roland Bouman
Roland Bouman

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

Mark Byers
Mark Byers

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

Related Questions