我正在使用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创建类似的东西,但如果它可以是单个查询,那将非常好。
所以我的问题是,我怎样才能得到理想的结果呢?
答案 0 :(得分:1)
您需要先加入所有表格。
然后,对于您想要的输出,您需要使用CONCAT
和GROUP_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;