SQL Server中使用CASE WHEN实现行转列的问题求助
问题场景
你需要实现的是典型的行转列需求,将source_member表中不同member_type对应的member_number,按member_id聚合为单独列输出,无匹配值返回NULL。
原始表样例数据
| member_id | member_number | member_type |
|---|---|---|
| 1511 | 99084213654 | CarMember |
| 1511 | 4435654121 | TaxiMember |
| 1511 | AA11133 | BusMember |
| 6612 | 97970897131 | CarMember |
| 6612 | AA23564 | BusMember |
预期输出
| member_id | CarMember | TaxiMember |
|---|---|---|
| 1511 | 99084213654 | 4435654121 |
| 6612 | 97970897131 | NULL |
错误原因分析
你写的CTE逻辑只是对每行做了字段值判断拆分,没有做聚合,最终查询会返回和原始表相同行数的结果,每个member_id对应多条记录,非当前类型的字段值为NULL,不符合一行对应一个member_id的要求。
修正后的SQL代码
WITH stg_1 AS ( SELECT member_id, CASE WHEN member_type = 'CarMember' THEN member_number END AS CarMember, CASE WHEN member_type = 'TaxiMember' THEN member_number END AS TaxiMember FROM source_member ) SELECT member_id, MAX(CarMember) AS CarMember, MAX(TaxiMember) AS TaxiMember FROM stg_1 GROUP BY member_id;
如果你的SQL引擎支持更简洁的写法,也可以直接用条件聚合一步完成,不需要CTE:
SELECT member_id, MAX(CASE WHEN member_type = 'CarMember' THEN member_number END) AS CarMember, MAX(CASE WHEN member_type = 'TaxiMember' THEN member_number END) AS TaxiMember FROM source_member GROUP BY member_id;
逻辑说明
- 用
MAX()聚合函数的原因是:同一个member_id下对应类型的member_number最多只有1个有效值,其余都是NULL,聚合时会自动跳过NULL取到唯一的有效值;如果对应类型没有记录,聚合结果就会返回NULL,完全符合预期。 - 不需要额外加过滤条件排除
BusMember类型,因为CASE判断不会匹配该类型,聚合后不会影响结果。
内容的提问来源于stack exchange,提问作者madfrostx
相关产品推荐
相关产品推荐

