SQL Server Pivot列转行咨询:合并重复行实现EVT列转表头
SQL行转列问题解决建议
原始数据表
| id | EVT | DATE |
|---|---|---|
| 1 | M1 | 2022-01-01 |
| 1 | M2 | NULL |
| 1 | M3 | 2023-01-01 |
| 2 | M7 | 2024-01-01 |
| 2 | M9 | 2025-01-01 |
目标数据表
| id | M1 | M2 | M3 | M7 | M9 |
|---|---|---|---|---|---|
| 1 | 2022-01-01 | NULL | 2023-01-01 | NULL | NULL |
| 2 | NULL | NULL | NULL | 2024-01-01 | 2025-01-01 |
问题描述
使用PIVOT语句行转列时,同一id对应多行结果,未合并为单行:
尝试的SQL语句
select ID, M1, M2, M3, M7, M9 from Table pivot (MAX(DATE) FOR EVT in (M1, M2, M3, M7, M9)) AS P
错误结果
| id | M1 | M2 | M3 | M7 | M9 |
|---|---|---|---|---|---|
| 1 | 2022-01-01 | NULL | NULL | NULL | NULL |
| 1 | NULL | NULL | NULL | NULL | NULL |
| 1 | NULL | NULL | 2023-01-01 | NULL | NULL |
解决方案
方案一:优化PIVOT查询
问题源于原始表中存在DATE为NULL的行,部分数据库的PIVOT不会自动合并同一id的记录。通过子查询先明确数据源,再执行PIVOT即可:
SELECT id, M1, M2, M3, M7, M9 FROM ( SELECT id, EVT, DATE FROM YourTableName -- 替换为实际表名 ) AS SourceData PIVOT ( MAX(DATE) FOR EVT IN (M1, M2, M3, M7, M9) ) AS PivotResult;
方案二:CASE表达式+GROUP BY(兼容性更强)
如果PIVOT方案仍有问题,推荐使用兼容性覆盖所有数据库的CASE分组方式:
SELECT id, MAX(CASE WHEN EVT = 'M1' THEN DATE END) AS M1, MAX(CASE WHEN EVT = 'M2' THEN DATE END) AS M2, MAX(CASE WHEN EVT = 'M3' THEN DATE END) AS M3, MAX(CASE WHEN EVT = 'M7' THEN DATE END) AS M7, MAX(CASE WHEN EVT = 'M9' THEN DATE END) AS M9 FROM YourTableName -- 替换为实际表名 GROUP BY id;
该方式通过GROUP BY id合并同一id的所有行,MAX()函数自动忽略NULL值,保留对应EVT的有效DATE(若存在),无有效数据则保留NULL。
内容的提问来源于stack exchange,提问作者Abdel E
相关产品推荐
相关产品推荐

