简体   繁体   中英

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 | jason@email.com |
| 1       | phone | 555-123-4567    |
| 2       | email | justin@email.com|
| 2       | phone | 555-765-4321    |


query results:
| user_id | username | email            | phone        |
| 1       | jason    | jason@email.com  | 555-123-4567 |
| 2       | justin   | justin@email.com | 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';

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM