2020-10-28 12:49:08
在SQL中,将多行数据合并为一行可以通过多种函数和技巧实现,以下是具体方法及示例:
1. CONCAT 函数用途:将多行中的列值连接成单个字符串(通常需配合其他逻辑)。示例:将客户姓名各部分合并为全名(单行处理,非分组):
SELECT CONCAT(first_name, ' ', middle_name, ' ', last_name) AS full_nameFROM customer;注意:此方法不涉及分组,仅处理单行内的列拼接。
2. GROUP_CONCAT 函数(MySQL)用途:将分组后的多行值合并为一个字符串,默认用逗号分隔。示例:按产品类别分组,合并同类产品名称:
SELECT product_category, GROUP_CONCAT(product_name) AS product_listFROM ordersGROUP BY product_category;扩展:可自定义分隔符或去重:
GROUP_CONCAT(DISTINCT product_name ORDER BY product_name SEPARATOR '|')3. STRING_AGG 函数(SQL Server/PostgreSQL)用途:类似GROUP_CONCAT,但支持更灵活的分隔符和排序。示例:按部门分组,合并员工技能并用逗号分隔:
SELECT department, STRING_AGG(skill, ', ') AS skill_setFROM employeeGROUP BY department;扩展:支持排序:
STRING_AGG(skill, ', ') WITHIN GROUP (ORDER BY skill DESC)4. FOR XML PATH('')(SQL Server)用途:将多行结果转换为XML字符串,再提取为单行文本。示例:将所有发票行合并为XML格式的单行字符串:
SELECT (SELECT * FROM invoice FOR XML PATH('')) AS combined_xml;进阶:结合STUFF去除前导分隔符(如逗号):
SELECT STUFF( (SELECT ',' + product_name FROM orders FOR XML PATH('')), 1, 1, '') AS product_list;5. LISTAGG 函数(Oracle)用途:Oracle中实现类似GROUP_CONCAT的功能。示例:合并部门员工姓名:
SELECT department, LISTAGG(employee_name, '; ') WITHIN GROUP (ORDER BY hire_date)FROM employeesGROUP BY department;6. ARRAY_AGG 或 JSON_AGG(PostgreSQL)用途:将多行聚合为数组或JSON格式。示例:生成部门技能JSON数组:
SELECT department, JSON_AGG(skill) AS skillsFROM employeeGROUP BY department;关键注意事项MySQL用GROUP_CONCAT,SQL Server用STRING_AGG或FOR XML PATH,Oracle用LISTAGG。
大数据量时,字符串聚合可能导致性能问题,需谨慎使用。
明确指定分隔符(如, )避免结果难以解析。
部分函数支持DISTINCT或ORDER BY子句优化结果。
MySQL:GROUP_CONCAT
SQL Server:STRING_AGG或FOR XML PATH
Oracle:LISTAGG
根据数据库类型和需求选择合适方法,可高效实现多行合并。