MySQL 查询:连接表并将记录显示为单行中的逗号分隔字符串

Posted

技术标签:

【中文标题】MySQL 查询:连接表并将记录显示为单行中的逗号分隔字符串【英文标题】:MySQL query: Join tables and display records as comma separated string in a single row 【发布时间】:2012-09-05 05:54:32 【问题描述】:

假设我的 mysql 数据库中有以下两个表:

Table 1:: EMP: EmpID, EmpName
eg. (1, 'John'), (2,'Alex'),(3,'Tom')

Table 2:: Team: TeamID, ManagerID, MemberID
eg. record1: (Team1, 1, 2), record2: (Team1, 1, 3) 

所以有一个 ID 为 team1 的团队,John 是经理,Alex 和 Tom 是它的成员。

我想以如下方式在屏幕上显示 Team 表的记录

| Team  | Manager | Members   |
| team1 | John    | Alex, Tom |

什么应该是 SQL 查询,它将连接上述两个表并在基于 memberID 时返回成员的名称。

结果也将显示为 1 行,其中包含所有团队成员,以逗号分隔。

如果有更好的方法来设计这两个表,那么也请提出建议。将不胜感激。

谢谢。

【问题讨论】:

【参考方案1】:

我认为您需要使用 GROUP_CONCATGROUP_CONCAT() 函数用于将列值连接成单个字符串。如果您要以其他方式执行多行查找然后在客户端将它们连接起来,这将非常有用。

SELECT  b.TeamID as TeamName, 
        a.EmpName as Manager,
        GROUP_CONCAT(c.EmpName) Members
FROM    Emp a
            INNER JOIN Team b
                ON a.EmpID = b.ManagerID
            INNER JOIN  Emp c
                ON b.MemberID = c.EmpID
GROUP BY b.TeamID, a.EmpName

您还可以更改分隔符和排序

GROUP_CONCAT( c.EmpName SEPARATOR '-' ),...
GROUP_CONCAT( c.EmpName ORDER BY c.EmpName DESC ),...

SQLFiddle Demo

【讨论】:

您知道 SQL Server 中是否有等效的“group_concat”函数吗?我现在想知道我是否一直这样做! @Michael 不,但你可以模拟它。 Click this LINK @Michael 这是给你的SQLFiddle Demo for MSSQL。这对你有帮助。 @Michael 很高兴你问到。我还想知道如何在 Oracle、DB2 等数据库中执行此操作? @Gaurav Here's Oracle Version of GROUP_CONCAT【参考方案2】:

使用GROUP_CONCAT(expr),您可以尝试类似

此函数返回一个字符串结果,其中包含连接的非 NULL 来自一个组的值。如果没有非 NULL 值,则返回 NULL。 组中值之间的默认分隔符是逗号(“,”)。

SELECT  t.TeamID Team,
        m.EmpName manager,
        GROUP_CONCAT(mem.EmpName) Members
FROM    Team t INNER JOIN
        Emp m   ON  t.ManagerID = m.EmpID INNER JOIN
        Emp mem ON  t.MemberID = mem.EmpID
GROUP BY    t.TeamID Team,
            m.EmpName

【讨论】:

【参考方案3】:

您需要加入EMP表两次,并使用group_concat单独列出成员。

select TeamID as Team, 
       e2.EmpName as Manager,
       group_concat(e1.EmpName) as Members
from Team t
left outer join EMP e1 on t.MemberID = e1.EmpID
left outer join EMP e2 on t.ManagerID = e2.EmpID
group by TeamID

如果您使用left outer join,那么即使团队中没有经理或成员,您也会得到结果。如果您只想要有成员和经理的团队,您可以使用inner join

【讨论】:

【参考方案4】:

用这个定义定义一个名为 vTeam 的视图:

选择 dbo.Team.TeamID、dbo.EMP.EmpName AS 经理、EMP_1.EmpName AS Member, EMP_1.EmpID AS MemberID, dbo.EMP.EmpID AS ManagerID FROM dbo.EMP AS EMP_1 右外连接 dbo.Team ON EMP_1.EmpID = dbo.Team.MemberID 左外连接 dbo.EMP ON dbo.Team.ManagerID = dbo.EMP.EmpID

这个查询会给你结果:

SELECT TeamID, Manager, MemberList = STUFF(( SELECT ',' + Member FROM vTeam as xx WHERE xx.TeamID = x.TeamID 和 x.Manager = xx.Manager FOR XML PATH(''), TYPE).value('.[1]', 'nvarchar(max)'), 1, 1, '') FROM dbo.vTeam AS x GROUP BY TeamID,Manager;

团队 1 约翰·亚历克斯、汤姆 Team2 亚历克斯·约翰、亚历克斯、汤姆

【讨论】:

以上是关于MySQL 查询:连接表并将记录显示为单行中的逗号分隔字符串的主要内容,如果未能解决你的问题,请参考以下文章

mysql left join 左连接查询关联n多张表

逗号分隔的连接和MySQL中的语法连接有啥区别? [复制]

mysql左连接和右连接的区别

如何在mysql中将单行插入查询重构为多行插入查询?

mysql-面试-外连接查询

mysql left join 左连接查询关联n多张表