关联表时将单列拆分为两列的SQL实现问题
解决思路与SQL实现方案
要实现将t2中不同TypeId的Description拆分到同一行,核心是通过条件聚合或者**透视(PIVOT)**将多行数据合并为单行,同时关联t1的信息。以下提供两种通用方案:
方案一:CASE表达式 + GROUP BY(通用所有SQL数据库)
这种方法兼容性最强,无需依赖数据库特定语法:
SELECT t1.[Reference #], t1.Reference, MAX(CASE WHEN t2.TypeId = 60 THEN t2.Description END) AS [No of Bedrooms], MAX(CASE WHEN t2.TypeId = 61 THEN t2.Description END) AS [Zone] FROM t1 LEFT JOIN t2 ON t1.Reference = t2.Reference AND t2.TypeId IN (60, 61) -- 只关联需要的TypeId,提升效率 GROUP BY t1.[Reference #], t1.Reference;
说明:
- 用
CASE表达式分别筛选TypeId=60和61的Description,未匹配到的会返回NULL - 通过
GROUP BY按t1的Reference #和Reference分组,用MAX(或MIN,只要每个分组内对应TypeId只有一条数据)聚合,将多行结果合并为单行
方案二:PIVOT透视(适用于支持PIVOT的数据库,如SQL Server、Oracle)
如果你的数据库支持PIVOT语法,可以更简洁实现:
SELECT [Reference #], Reference, [60] AS [No of Bedrooms], [61] AS [Zone] FROM ( -- 先获取关联后的基础数据集 SELECT t1.[Reference #], t1.Reference, t2.TypeId, t2.Description FROM t1 LEFT JOIN t2 ON t1.Reference = t2.Reference AND t2.TypeId IN (60, 61) ) AS SourceData PIVOT ( MAX(Description) -- 聚合函数,确保每个TypeId对应唯一值 FOR TypeId IN ([60], [61]) -- 指定要透视的TypeId值 ) AS PivotTable;
关键注意点:
- 确保每个
Reference #+ TypeId组合在t2中只有一条记录,否则需要根据实际情况选择合适的聚合函数(如MAX/MIN/STRING_AGG) - 使用
LEFT JOIN可以保留t1中即使没有对应t2数据的行,此时对应的列会显示NULL,如果需要只保留有匹配的行,可改为INNER JOIN
内容的提问来源于stack exchange,提问作者user2293224
相关产品推荐
相关产品推荐

