SQL Server如何实现行级数据转列级 解决两表连接笛卡尔积问题
解决方案
直接JOIN产生笛卡尔积的核心原因是员工表和手机号表是一对多关系,关联后每个员工会生成多条手机号记录,只要在关联后按员工维度做聚合,搭配条件判断提取指定类型的手机号即可实现行转列,以下是两种可直接运行的实现方式:
方式1:条件聚合(全版本兼容,推荐)
该写法无版本限制,逻辑直观易维护,性能表现稳定:
SELECT t1.emp_Id, t1.name, t1.age, MAX(CASE WHEN t2.type = 201 THEN t2.ph_no END) AS [201#], MAX(CASE WHEN t2.type = 203 THEN t2.ph_no END) AS [203#] FROM 表1 t1 LEFT JOIN 表2 t2 ON t1.emp_Id = t2.emp_id AND t2.type IN (201, 203) -- 提前过滤不需要的手机号类型,减少无效计算 GROUP BY t1.emp_Id, t1.name, t1.age
方式2:PIVOT运算符实现(SQL Server 2005+支持)
用SQL Server原生行转列语法实现,逻辑更聚焦行转列规则:
SELECT emp_Id, name, age, [201] AS [201#], [203] AS [203#] FROM ( SELECT t1.emp_Id, t1.name, t1.age, t2.type, t2.ph_no FROM 表1 t1 LEFT JOIN 表2 t2 ON t1.emp_Id = t2.emp_id AND t2.type IN (201, 203) ) base_data PIVOT ( MAX(ph_no) FOR type IN ([201], [203]) ) pivot_result
结果验证
两种写法执行后返回结果完全匹配需求:
| emp_Id | name | age | 201# | 203# |
|---|---|---|---|---|
| 101 | aaa | 20 | 8888 | 7777 |
| 102 | bbb | 30 | 1111 | 3333 |
注意:上述代码里的
表1/表2请替换为你实际环境里的真实表名。
内容的提问来源于stack exchange,提问作者Srinivasan
相关产品推荐
相关产品推荐

