如何在SQL查询中将记录转换为字段实现行转列?
问题描述
需要从TotalVaccinations表生成指定格式的查询结果:
期望结果表
| Date | Australia | United States | Germany |
|---|---|---|---|
| 24th | 13000 | 14003 | 25608 |
| 25th | 24800 | 20080 | 30502 |
原始数据表格TotalVaccinations
| Country | Date | TotalVaccinations |
|---|---|---|
| AUS | 24th | 13000 |
| USA | 24th | 14003 |
| DEU | 24th | 25608 |
| AUS | 25th | 24800 |
| USA | 25th | 20080 |
| DEU | 25th | 30502 |
尝试执行以下SQL语句:
Select Date, A.TotalFullyVaccinated AS 'Australia', B.TotalFullyVaccinated AS 'United States' From TotalVaccinations A, TotalVaccinations B Where A.Date = B.Date And A.Country= 'AUS' Or B.Country= 'USA' ;
但查询结果中的Australia字段为空,请问该如何正确实现需求?
解决方案
错误原因分析
你的SQL存在两个核心问题:
- 字段名错误:原始表的目标字段是
TotalVaccinations,但你写了TotalFullyVaccinated,字段不存在直接导致返回空值。 - 逻辑运算符优先级问题:
AND优先级高于OR,原条件会被解析为(A.Date = B.Date AND A.Country= 'AUS') OR B.Country= 'USA',生成大量不符合预期的关联数据,进一步加剧结果异常。
推荐实现方式:条件聚合(行转列最优解)
这是处理行转列场景最简洁高效的写法:
SELECT Date, MAX(CASE WHEN Country = 'AUS' THEN TotalVaccinations END) AS Australia, MAX(CASE WHEN Country = 'USA' THEN TotalVaccinations END) AS 'United States', MAX(CASE WHEN Country = 'DEU' THEN TotalVaccinations END) AS Germany FROM TotalVaccinations GROUP BY Date ORDER BY Date;
原理说明
- 用
CASE语句按国家筛选对应数据,每个国家的数值仅在匹配行出现,其余行返回NULL。 - 用
MAX()聚合函数(每个日期每个国家仅有一条数据,用SUM()效果一致)将同一日期的多国家数据聚合到一行。 - 按
Date分组后,直接得到每个日期的各国家疫苗接种数。
备选实现方式:修正自连接写法
如果你偏好自连接方式,需修正字段名和逻辑条件,同时补充德国的关联表:
SELECT A.Date, A.TotalVaccinations AS Australia, B.TotalVaccinations AS 'United States', C.TotalVaccinations AS Germany FROM TotalVaccinations A JOIN TotalVaccinations B ON A.Date = B.Date AND B.Country = 'USA' JOIN TotalVaccinations C ON A.Date = C.Date AND C.Country = 'DEU' WHERE A.Country = 'AUS';
注意事项
- 若存在某日期下部分国家无数据的情况,
JOIN会过滤掉该日期;如需保留所有日期,改用LEFT JOIN。 - 必须使用正确的字段名
TotalVaccinations。
内容的提问来源于stack exchange,提问作者Goh Kian Seen
相关产品推荐
相关产品推荐

