0

我有两个 mysql 表,我想在一个查询中合并在一起。最好用一个例子来描述:

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 |

您可以假设所有用户的密钥都非常统一(即所有用户都有电子邮件和电话)。我的第一个想法是做这样的事情,但我很好奇是否有更好的方法:

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';
4

2 回答 2

3

所有用户都有电子邮件和电话

那么为什么不在原始表中为它们添加列呢?

table: users
| user_id | username | email | phone  |
| 1       | jason    | ....  | ....   |
| 2       | justin   | ....  | ....   |

它将使查询更加容易和快捷。

您使用的设计称为实体属性值(EAV),通常在属性很多但填充稀疏的情况下很有用。

假设您不能或不想更改表设计,我对您的查询所做的唯一更改是不使用SELECT *. 明确列出列。

于 2012-04-27T22:18:47.427 回答
0

我同意@Mark Ba​​yers。

然而,如果你坚持你的设计,你应该考虑这一点:一个用户是否有可能拥有不止一封电子邮件?或不止一部手机?如果是这种情况,那么您将获得每位用户的所有电话和电子邮件组合。

如果您只想为每个用户提供一行,并在各个字段中包含所有数据,您可以尝试以下操作:

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
于 2012-04-27T22:26:18.753 回答