如何在Oracle SQL中将同一样本ID的多测试名合并至单行?
Oracle SQL中合并同Sample ID的测试名称到单行的方法
在Oracle中,要实现类似SQL Server STRING_AGG的字符串聚合功能,将同一sample_id对应的多个测试名称合并为单行,主要有两种常用方法:
方法一:使用LISTAGG(推荐,Oracle 11g R2及以上版本)
LISTAGG是Oracle官方提供的字符串聚合函数,支持自定义分隔符和排序,语法规范且兼容性好。
修改后的查询语句如下:
SELECT d.sample_id, LISTAGG(c.test_name_eng, ', ') WITHIN GROUP (ORDER BY c.test_name_eng) AS test_name FROM mr_files a JOIN lab_sample_header b ON a.patient_no = b.patient_no JOIN lab_sample_details d ON b.order_id = d.order_id AND b.sample_id = d.sample_id JOIN lab_tests c ON c.test_no = d.test_no JOIN lab_orders o ON a.patient_no = o.patient_no AND b.order_id = o.order_id WHERE d.order_id = 2025000045 AND d.sample_status = 2 GROUP BY d.sample_id;
关键说明:
LISTAGG(c.test_name_eng, ', '):将同一sample_id分组下的test_name_eng用,连接WITHIN GROUP (ORDER BY c.test_name_eng):指定合并时测试名称的排序规则,可替换为test_no等其他字段GROUP BY d.sample_id:按sample_id分组,确保每个样本ID仅返回一行- 移除了原查询的
DISTINCT,因为GROUP BY已实现分组去重
方法二:使用WM_CONCAT(适用于Oracle 11g之前版本)
WM_CONCAT是非官方函数,Oracle并未正式支持,仅部分旧版本可用,默认分隔符为逗号,无法自定义。
示例语句:
SELECT d.sample_id, WM_CONCAT(c.test_name_eng) AS test_name FROM mr_files a, lab_sample_header b, lab_tests c, lab_sample_details d, lab_orders o WHERE a.patient_no = b.patient_no AND b.order_id = d.order_id AND c.test_no = d.test_no AND a.patient_no = o.patient_no AND b.order_id = o.order_id AND d.order_id = 2025000045 AND b.sample_id = d.sample_id AND d.sample_status = 2 GROUP BY d.sample_id;
注意事项:
WM_CONCAT返回类型可能为CLOB或VARCHAR2,不同版本存在差异- 官方不推荐使用,后续版本可能移除,优先选择
LISTAGG
执行结果
运行上述推荐方法的语句后,将得到期望输出:
SAMPLE_ID TEST_NAME BCH-25-100 CALCIUM , SODIUM , ALBUMIN HE-25-43 CBC
内容的提问来源于stack exchange,提问作者Abdullah
相关产品推荐
相关产品推荐

