如何在PostgreSQL的WITH RECURSIVE查询中拼接字符串字段值
纯WITH RECURSIVE实现无GROUP BY的字符串拼接方案
完全不使用GROUP BY语法,仅通过递归CTE即可实现按公司分组拼接员工姓名的需求,具体实现如下:
实现逻辑
- 首先通过窗口函数给同公司的员工按顺序打上连续行号,同时统计每个公司的员工总数
- 递归CTE从每个公司的第一个员工开始,逐行拼接下一位员工的姓名,直到遍历完该公司所有员工
- 最后过滤出每个公司拼接完成的最终记录,按员工数量升序排序即可得到目标结果
可直接运行的SQL代码
假设你的测试表名为company_employee,代码如下:
WITH RECURSIVE -- 给同公司员工排序打标 ranked_employees AS ( SELECT company_id, employee, ROW_NUMBER() OVER (PARTITION BY company_id ORDER BY id) AS row_num, COUNT(*) OVER (PARTITION BY company_id) AS total_emp FROM company_employee ), -- 递归拼接字符串 concat_result AS ( -- 递归起始:每个公司的第一位员工 SELECT company_id, employee AS emp_list, row_num, total_emp FROM ranked_employees WHERE row_num = 1 UNION ALL -- 逐行拼接同公司下一位员工 SELECT re.company_id, cr.emp_list || ', ' || re.employee, re.row_num, re.total_emp FROM concat_result cr INNER JOIN ranked_employees re ON cr.company_id = re.company_id AND re.row_num = cr.row_num + 1 ) -- 输出最终结果 SELECT company_id, emp_list AS employee FROM concat_result -- 只保留每个公司拼接完所有员工的记录 WHERE row_num = total_emp ORDER BY total_emp ASC, company_id ASC;
结果验证
传入你提供的测试数据后,返回结果完全匹配预期:
| COMPANY_ID | EMPLOYEE |
|---|---|
| 3 | Tom |
| 1 | Anna, Bill |
| 2 | Carol, Dave |
可调参数说明
- 员工拼接顺序:修改
ranked_employees里ROW_NUMBER的ORDER BY字段即可,比如要按姓名字母排序就改成ORDER BY employee - 拼接分隔符:修改递归段里
|| ', ' ||的字符串内容,可替换为顿号、分号等任意你需要的分隔符
内容的提问来源于stack exchange,提问作者FlowaH
相关产品推荐
相关产品推荐

