如何改进多次连接同一表的SQL

时间:2019-04-08 06:33:09

标签: mysql left-join

我正在维护使用MYSQL和PHP的项目,我发现数据库结构是这样的。

table user

+----+-------+
| id | name  |
+----+-------+
|  1 | Tom   |
|  2 | John  |
|  3 | Peter |
|  4 | Mary  |
+----+-------+

table data

+--------+----------+----------+
| userid |   type   | content  |
+--------+----------+----------+
|      1 | gender   | male     |
|      1 | comment  | Hello    |
|      1 | phone    | 12345678 |
|      1 | username | tom      |
|    ... | ...      | ...      |
+--------+----------+----------+

我需要编写SQL来获取像这样的数据

+-----+------+--------+----------+---------+----------+
| id  | name | gender |  phone   | comment | username |
+-----+------+--------+----------+---------+----------+
|   1 | Tom  | male   | 12345678 | Hello   | tom      |
| ... | ...  | ...    |      ... | ...     | ...      |
+-----+------+--------+----------+---------+----------+

因此,SQL将是

SELECT user.id as "id",user.name as "name",d1.content as 'gender', d2....... FROM user
LEFT JOIN data d1 on d1.userid = user.id and d1.type = 'gender'....
LEFT JOIN...
LEFT JOIN...
LEFT JOIN...

它可以工作,但我认为这太复杂且难以维护。性能也不佳。此外,当我向表data中添加更多类型时,我需要向所有表中添加更多join查询。

如果SQL已经从表data中获取数据,它是否能够过滤它而无需再次联接它?

有什么想法可以使我的SQL查询更简单,更快捷?

1 个答案:

答案 0 :(得分:2)

另一种方法是使用条件聚合:

SELECT u.id,
       MAX(CASE WHEN d.type = 'gender' THEN content END) AS gender,
       MAX(CASE WHEN d.type = 'comment' THEN content END) AS comment,
       MAX(CASE WHEN d.type = 'phone' THEN content END) AS phone,
       MAX(CASE WHEN d.type = 'username' THEN content END) AS username
FROM user u
LEFT JOIN data d ON d.userid = u.id
WHERE u.id = 1
GROUP BY u.id

输出:

id  gender  comment phone       username
1   male    Hello   12345678    tom

Demo on dbfiddle