如何在LEFT JOIN的CASE语句后对多行Type与地址进行SQL拼接?
问题:SQL按AppID聚合拼接Type与地址
数据表结构
Table1(应用表)
| AppID | Desc |
|---|---|
| 1 | App1 |
| 2 | App2 |
Table2(担保物表)
| CollateralID | Type | AppID |
|---|---|---|
| 1 | Home | 1 |
| 2 | Condo | 1 |
| 3 | Condo | 2 |
Table3(地址表)
| TitleID | Address1 | Address2 | Address3 | CollateralID |
|---|---|---|---|---|
| 1 | Add1a | Add2a | Add3a | 1 |
| 2 | Add1b | Add2b | Null | 2 |
| 3 | Add1c | Add2c | Null | 3 |
期望结果
| AppID | Desc | Type | Complete Address |
|---|---|---|---|
| 1 | App1 | Home; Condo | Add1a + Add2a + Add3a; Add1b + Add2b |
| 2 | App2 | Condo | Add1c + Add2c |
当前尝试的SQL代码
SELECT app.AppID AS AppID, app.Desc AS Desc, details.type AS Type, details.compadd AS "Complete Address" FROM Table1 app LEFT JOIN (SELECT tab2.AppID, tab2.Type, CASE WHEN tab2.Type = 'HOME' THEN tab3.Address1 || ' ' || tab3.Address2 || ' ' || tab3.Address3 WHEN tab2.Type = 'CONDO' THEN tab3.Address1 || ' ' || tab3.Address2 END AS compadd FROM Table2 tab2 JOIN Table3 tab3 ON tab2.CollateralID = tab3.CollateralID ) details ON app.AppdID = tab2.AppID
遇到的问题
无法按同一AppID对Type字段和拼接后的地址进行分组聚合,得到期望的拼接结果。
解决方案
要实现按AppID聚合拼接,需使用各SQL方言对应的字符串聚合函数,同时先处理地址的拼接逻辑,再对结果进行分组聚合:
1. MySQL / MariaDB 实现
使用GROUP_CONCAT函数:
SELECT app.AppID, app.Desc, GROUP_CONCAT(tab2.Type SEPARATOR '; ') AS Type, GROUP_CONCAT( CASE WHEN tab2.Type = 'HOME' THEN CONCAT_WS(' + ', tab3.Address1, tab3.Address2, tab3.Address3) WHEN tab2.Type = 'CONDO' THEN CONCAT_WS(' + ', tab3.Address1, tab3.Address2) END SEPARATOR '; ' ) AS `Complete Address` FROM Table1 app LEFT JOIN Table2 tab2 ON app.AppID = tab2.AppID LEFT JOIN Table3 tab3 ON tab2.CollateralID = tab3.CollateralID GROUP BY app.AppID, app.Desc;
2. PostgreSQL / SQL Server 实现
使用STRING_AGG函数:
SELECT app.AppID, app.Desc, STRING_AGG(tab2.Type, '; ') AS Type, STRING_AGG( CASE WHEN tab2.Type = 'HOME' THEN COALESCE(tab3.Address1, '') || COALESCE(' + ' || tab3.Address2, '') || COALESCE(' + ' || tab3.Address3, '') WHEN tab2.Type = 'CONDO' THEN COALESCE(tab3.Address1, '') || COALESCE(' + ' || tab3.Address2, '') END, '; ' ) AS "Complete Address" FROM Table1 app LEFT JOIN Table2 tab2 ON app.AppID = tab2.AppID LEFT JOIN Table3 tab3 ON tab2.CollateralID = tab3.CollateralID GROUP BY app.AppID, app.Desc;
3. Oracle 实现
使用LISTAGG函数:
SELECT app.AppID, app.Desc, LISTAGG(tab2.Type, '; ') WITHIN GROUP (ORDER BY tab2.CollateralID) AS Type, LISTAGG( CASE WHEN tab2.Type = 'HOME' THEN tab3.Address1 || ' + ' || tab3.Address2 || ' + ' || tab3.Address3 WHEN tab2.Type = 'CONDO' THEN tab3.Address1 || ' + ' || tab3.Address2 END, '; ' ) WITHIN GROUP (ORDER BY tab2.CollateralID) AS "Complete Address" FROM Table1 app LEFT JOIN Table2 tab2 ON app.AppID = tab2.AppID LEFT JOIN Table3 tab3 ON tab2.CollateralID = tab3.CollateralID GROUP BY app.AppID, app.Desc;
关键说明
- 原SQL中的
AppdID是拼写错误,需修正为AppID - 使用
CONCAT_WS(MySQL)或COALESCE(其他方言)可以避免Null值导致的多余分隔符 - 聚合函数中添加
ORDER BY子句可以保证拼接顺序与数据顺序一致
内容的提问来源于stack exchange,提问作者sellavsert
相关产品推荐
相关产品推荐

