使用桥将列组合成单列

时间:2016-12-09 15:08:39

标签: mysql database

我正在使用mysql数据库,但我遇到了问题。我有一个用户列表,看起来像这样。

   Users
+----+------+
| ID | Name | 
+----+------+
|  1 | Jim  |
|  2 | Cal  |
|  3 | Rob  |
|  4 | John |
|  5 | Paul |
+----+------+

现在我还有两张桌子,

   Teams           Role
+----+----------+   +---+------+
| ID | NameTeam |   |ID | Role |
+----+----------+   +---+------+
|  1 | Team1    |   | 1 |Leader|
|  2 | Team2    |   | 2 |Member|
|  3 | Team3    |   | 3 |Role3 |
|  4 | Team4    |   | 4 |Role4 |
|  5 | Team5    |   | 5 |Role5 |
+----+----------+   +---+------+

请注意,并非所有ID都是主键。

最后,有一个表作为上表的桥梁。

           Bridge
+---------+--------+--------+
| ID_team | ID_user| ID_role|
+---------+--------+--------+
|  1      | 1      | 1      |
|  1      | 2      | 2      |
|  1      | 3      | 3      |
|  2      | 4      | 1      |
|  2      | 5      | 2      |
|  2      | 1      | 3      |
+---------+--------+--------+

所有这三列都是外键,链接到三个表Users,Teams和Role中的主键。

我想要的是所有用户的列表,并在一列中列出他们所属团队的信息,以及他们在该团队中的角色。我想我可以通过左连接来做到这一点但是用户可以链接到多个团队,然后该行将重复。

到目前为止我的查询:

select * from Users 
LEFT OUTER JOIN Bridge
ON Bridge.UserID = Users.UserID;

这导致重复,如:

    Result 
+----+------+---------+--------+--------+
| ID | Name | ID_team | ID_user| ID_role|
+----+------+---------+--------+--------+
|  1 | Jim  |  1      | 1      | 1      | << Twice Jim here
|  1 | Jim  |  2      | 1      | 3      | <<
|  2 | Cal  |  1      | 2      | 2      |
|  3 | Rob  |  1      | 3      | 3      |
|  4 | John |  2      | 4      | 1      |
|  5 | Paul |  2      | 5      | 2      |
+----+------+---------+--------+--------+


    Desired result
+----+------+----------------------------+
| ID | Name | Team and role              |
+----+------+----------------------------+
|  1 | Jim  |  Team1: Leader,Team2:role3 | <<Nice sum up.
|  2 | Cal  |  Team1: Member             |
|  3 | Rob  |  Team1: Role3              |
|  4 | John |  Team2: Leader             |
|  5 | Paul |  Team2: Member             |
+----+------+----------------------------+

使用单个查询甚至可以实现这样的效果吗?如果不是,我总是可以通过使用php创建类似的东西,但如果它可以是单个查询,那将非常好。

所以我的问题是,我怎样才能得到理想的结果呢?

1 个答案:

答案 0 :(得分:1)

您需要先加入所有表格。

然后,对于您想要的输出,您需要使用CONCATGROUP_CONCAT功能。

SELECT 
U.ID,
U.Name,
GROUP_CONCAT(CONCAT(T.NameTeam,':',R.Role)) AS 'Team and Role'
FROM Bridge B
INNER JOIN Users U ON U.ID = B.ID_user 
INNER JOIN Teams T ON T.ID = B.ID_team 
INNER JOIN Role R ON R.ID = B.ID_role
GROUP BY B.ID_user

修改

为了获得所有用户的结果,无论Bridge表中是否存在相应的记录:

SELECT 
U.ID,
U.Name,
GROUP_CONCAT(CONCAT(T.NameTeam,':',R.Role)) AS 'Team and Role'
FROM Users U 
LEFT JOIN Bridge B ON U.ID = B.ID_user 
LEFT JOIN Teams T ON T.ID = B.ID_team 
LEFT JOIN Role R ON R.ID = B.ID_role
GROUP BY U.ID;

SEE DEMO