如何在MySQL/SQL中连接两张表并将多行合并至单个单元格?
解决MySQL及通用SQL中多行数据合并到单个单元格的问题
嘿,我来帮你搞定这两个SQL问题!你现在的左连接查询会把每个订单拆成单独的行,要把同一个客户的订单ID合并到一个单元格里,咱们分情况来说:
一、MySQL中的实现方法
MySQL专门提供了GROUP_CONCAT()函数来做这种多行字符串拼接的操作,结合分组就能轻松实现需求。你只需要修改原来的查询语句:
SELECT Customers.CustomerName, COALESCE(GROUP_CONCAT(Orders.OrderID SEPARATOR ', '), '') AS OrderIDs FROM Customers LEFT JOIN Orders ON Customers.CustomerID = Orders.CustomerID GROUP BY Customers.CustomerID, Customers.CustomerName;
这里给你拆解下关键部分:
GROUP BY Customers.CustomerID, Customers.CustomerName:按客户ID和姓名分组,确保同一个客户的所有订单会被归到一起(用CustomerID分组更稳妥,避免出现同名不同客户的情况)GROUP_CONCAT(Orders.OrderID SEPARATOR ', '):把分组内的所有OrderID拼接成一个字符串,用逗号加空格分隔,你可以换成其他分隔符比如' | 'COALESCE(..., ''):如果客户没有任何订单,会返回NULL,用这个函数把NULL替换成空字符串,结果更美观
二、通用SQL的实现方法
不同数据库的字符串聚合函数不一样,下面给你列举几种常见数据库的写法:
PostgreSQL
用STRING_AGG()函数,语法和MySQL类似,注意要把数值类型的OrderID转成文本:
SELECT Customers.CustomerName, COALESCE(STRING_AGG(CAST(Orders.OrderID AS TEXT), ', '), '') AS OrderIDs FROM Customers LEFT JOIN Orders ON Customers.CustomerID = Orders.CustomerID GROUP BY Customers.CustomerID, Customers.CustomerName;
SQL Server
- 2017及以上版本:支持
STRING_AGG(),用法简单:
SELECT Customers.CustomerName, COALESCE(STRING_AGG(CAST(Orders.OrderID AS VARCHAR), ', '), '') AS OrderIDs FROM Customers LEFT JOIN Orders ON Customers.CustomerID = Orders.CustomerID GROUP BY Customers.CustomerID, Customers.CustomerName;
- 旧版本(2016及以下):需要用
FOR XML PATH的技巧来拼接:
SELECT c.CustomerName, STUFF(( SELECT ', ' + CAST(o.OrderID AS VARCHAR) FROM Orders o WHERE o.CustomerID = c.CustomerID FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)'), 1, 2, '') AS OrderIDs FROM Customers c;
Oracle
用LISTAGG()函数,还可以指定拼接的顺序:
SELECT Customers.CustomerName, COALESCE(LISTAGG(Orders.OrderID, ', ') WITHIN GROUP (ORDER BY Orders.OrderID), '') AS OrderIDs FROM Customers LEFT JOIN Orders ON Customers.CustomerID = Orders.CustomerID GROUP BY Customers.CustomerName;
内容的提问来源于stack exchange,提问作者Yash M. Hanj
相关产品推荐
相关产品推荐

