SQL技术问询:相同ID对应不同值的多行如何合并为单行展示
现有查询语法问题修正
先修复你当前SQL的硬错误,确保查询可正常运行,再做合并逻辑调整:
原SQL错误点
- 关联
name_address的ON条件缺失等于号,错误写法为rf.guest_name_id na.name_id - SELECT子句中
na.country和phone_number之间漏写逗号,错误拼接为na.country.phone_number - 此前用
DISTINCT去重是为了规避关联后产生的多行重复,但本质未从逻辑上解决多行合并的问题
修正后可运行的基础SQL
SELECT DISTINCT rf.resort, rf.guest_name_id, na.address1,na.address2,na.address3,na.address4, na.city,na.state,na.zip_code,na.country, np.phone_number FROM rep_reservation_fin_all rf LEFT JOIN name_address na ON rf.guest_name_id = na.name_id LEFT JOIN name_phone np ON rf.guest_name_id = np.name_id WHERE rf.guest_name_id = '3966078' AND na.primary_YN = 'Y' AND np.primary_YN = 'Y'
多行合并为单行的实现方案
你的核心诉求是相同guest_name_id下,同一字段的多个不同值合并为一个单元格展示,之前用PIVOT达不到预期的原因是:PIVOT是将固定枚举的行值转换为独立列(比如把"电话类型=手机/座机"拆成手机号、座机号两列),并不适配你当前同字段多值合并为单行的场景,直接用分组聚合+字符串拼接函数即可实现。
通用实现思路
- 把原来的
DISTINCT替换为按guest_name_id(及其他固定不变的维度字段,比如resort)分组 - 不需要合并的固定字段直接用
MAX()/MIN()取值即可 - 需要合并的多值字段用数据库对应的字符串聚合函数拼接,支持去重、自定义分隔符
不同数据库适配的拼接函数
- MySQL:用
GROUP_CONCAT(),示例:GROUP_CONCAT(DISTINCT np.phone_number SEPARATOR ', ') AS all_phone_list - Oracle:用
LISTAGG(),示例:LISTAGG(DISTINCT np.phone_number, ', ') WITHIN GROUP (ORDER BY np.phone_number) AS all_phone_list - SQL Server 2017及以上:用
STRING_AGG(),示例:STRING_AGG(np.phone_number, ', ') WITHIN GROUP (ORDER BY np.phone_number) AS all_phone_list - 低版本SQL Server:需要用
FOR XML PATH的方式实现字符串拼接
合并后示例SQL(以Oracle为例)
SELECT rf.resort, rf.guest_name_id, -- 主地址为单值,直接取聚合值即可 MAX(na.address1) AS address1, MAX(na.address2) AS address2, MAX(na.address3) AS address3, MAX(na.address4) AS address4, MAX(na.city) AS city, MAX(na.state) AS state, MAX(na.zip_code) AS zip_code, MAX(na.country) AS country, -- 合并同ID下的多个电话为单行 LISTAGG(DISTINCT np.phone_number, ', ') WITHIN GROUP (ORDER BY np.phone_number) AS all_phone_number FROM rep_reservation_fin_all rf LEFT JOIN name_address na ON rf.guest_name_id = na.name_id LEFT JOIN name_phone np ON rf.guest_name_id = np.name_id WHERE rf.guest_name_id = '3966078' AND na.primary_YN = 'Y' AND np.primary_YN = 'Y' GROUP BY rf.resort, rf.guest_name_id
排查提示:如果同ID下本该唯一的主地址/主电话仍出现多条,可先临时去掉
np.primary_YN = 'Y'的过滤条件,查询该ID下的标记是否存在多条主记录,调整过滤规则后再做合并即可。
内容的提问来源于stack exchange,提问作者BuffaloBill
相关产品推荐
相关产品推荐

