SQL实现:关联表字段合并为逗号分隔字符串并分组查询
解决SQL合并关联字段为逗号分隔字符串的问题
你的问题核心是需要按job_id分组,将关联的cost_code_id聚合为单个逗号分隔的字符串,同时避免分组报错。以下是具体解决方案:
问题原因分析
- 你原SQL中的
concat(',', job_costcodes.cost_code_id)仅对单个cost_code_id做字符串拼接,没有进行聚合操作,因此每个关联的cost_code_id会生成独立行。 - 添加
GROUP BY jobs.job_id后报错,是因为SQL的严格分组规则要求:SELECT列表中的非聚合字段必须全部包含在GROUP BY子句中。jobs.description既不在GROUP BY里,也没有被聚合函数包裹,所以数据库判定该字段的取值不明确。
分数据库的正确SQL实现
不同数据库提供了不同的字符串聚合函数,以下是主流数据库的实现方式:
1. MySQL/MariaDB
使用GROUP_CONCAT函数:
SELECT j.job_id, j.description, GROUP_CONCAT(jc.cost_code_id SEPARATOR ',') AS cost_code_ids FROM jobs j JOIN job_costcodes jc ON jc.job_id = j.job_id GROUP BY j.job_id, j.description;
GROUP_CONCAT会自动将分组内的cost_code_id用指定分隔符拼接- GROUP BY同时包含
job_id和description,符合严格分组规则,避免报错
2. SQL Server 2017+/Azure SQL
使用STRING_AGG函数:
SELECT j.job_id, j.description, STRING_AGG(jc.cost_code_id, ',') AS cost_code_ids FROM jobs j JOIN job_costcodes jc ON jc.job_id = j.job_id GROUP BY j.job_id, j.description;
3. PostgreSQL
使用STRING_AGG函数,注意需要将数值类型的cost_code_id转为字符串:
SELECT j.job_id, j.description, STRING_AGG(jc.cost_code_id::TEXT, ',') AS cost_code_ids FROM jobs j JOIN job_costcodes jc ON jc.job_id = j.job_id GROUP BY j.job_id, j.description;
4. Oracle 11gR2+
使用LISTAGG函数:
SELECT j.job_id, j.description, LISTAGG(jc.cost_code_id, ',') WITHIN GROUP (ORDER BY jc.cost_code_id) AS cost_code_ids FROM jobs j JOIN job_costcodes jc ON jc.job_id = j.job_id GROUP BY j.job_id, j.description;
WITHIN GROUP (ORDER BY ...)可以指定拼接的顺序,按需调整即可
内容的提问来源于stack exchange,提问作者J Doe
相关产品推荐
相关产品推荐

