Oracle SQL:同一ID对应多行数据合并为一行的实现问题
解决Oracle SQL中同一手机号多行数据合并为一行的问题
我懂你的需求啦——现在你的查询会同时按initiator_msisdn(手机号)和trx_type(交易类型)分组,所以同一个手机号下不同交易类型的记录会分成多行显示。要把这些行的交易信息合并到同一行,你可以用Oracle的LISTAGG字符串聚合函数来实现,这是官方推荐的方法,兼容性也更好。
具体解决方案
我们可以分两步来处理:
- 先通过CTE(公共表表达式)计算出每个手机号+交易类型对应的金额、佣金拼接字符串;
- 再用
LISTAGG把同一手机号的所有交易信息拼接成一个字段。
修改后的SQL如下:
-- 第一步:先计算每个手机号+交易类型的聚合结果 WITH trx_details AS ( SELECT initiator_msisdn, trx_type || '/' || SUM(trx_amt/100) || '/' || SUM(merchant_comm_amt/100) AS trx_info FROM LBI_DM_MK.T_M_INTERNAL_AUDIT_D WHERE DATA_DATE = '20180401' AND trx_status ='Completed' GROUP BY initiator_msisdn, trx_type ) -- 第二步:将同一手机号的所有交易信息合并为一行 SELECT initiator_msisdn, LISTAGG(trx_info, ', ') WITHIN GROUP (ORDER BY trx_type) AS agent_data FROM trx_details GROUP BY initiator_msisdn;
关键说明
LISTAGG(trx_info, ', '):把trx_info列的多行字符串用,分隔符拼接起来;WITHIN GROUP (ORDER BY trx_type):指定拼接时按交易类型排序,保证结果的顺序可控;- 如果你的Oracle版本比较旧(比如11g之前),
LISTAGG可能不支持,这时可以试试非官方的WM_CONCAT函数(注意不同版本可能有差异),把第二步的LISTAGG替换成WM_CONCAT(trx_info)即可。
内容的提问来源于stack exchange,提问作者khalidmehmoodawan




