sql - 将行透视到 Sql Server 中的列
问题描述
我有一个看起来像这样的示例表:
+------+-------------+---------+----------+
| Year | Country | Ranking | Category |
+------+-------------+---------+----------+
| 2018 | Ghana | 1 | Swimming |
| 2018 | Sweden | 2 | Swimming |
| 2018 | Costa Rica | 3 | Swimming |
| 2018 | Jordan | 1 | Sprint |
| 2018 | Thailand | 2 | Sprint |
| 2018 | Finland | 3 | Sprint |
| 2018 | Myanmar | 1 | Boxing |
| 2018 | Peru | 2 | Boxing |
| 2018 | Belgium | 3 | Boxing |
| 2017 | Nigeria | 1 | Swimming |
| 2017 | Philippines | 2 | Swimming |
| 2017 | Haiti | 3 | Swimming |
| 2017 | Netherlands | 1 | Sprint |
| 2017 | Macedonia | 2 | Sprint |
| 2017 | Kuwait | 3 | Sprint |
| 2017 | Malaysia | 1 | Boxing |
| 2017 | New Zealand | 2 | Boxing |
| 2017 | Palau | 3 | Boxing |
+------+-------------+---------+----------+
并且需要创建一个如下所示的报告:
+----------+---------+-------------+------------+
| Category | Ranking | 2017 | 2018 |
+----------+---------+-------------+------------+
| Swimming | 1 | Nigeria | Ghana |
| Swimming | 2 | Philippines | Sweden |
| Swimming | 3 | Haiti | Costa Rica |
| Sprint | 1 | Netherlands | Jordan |
| Sprint | 2 | Macedonia | Thailand |
| Sprint | 3 | Kuwait | Finland |
| Boxing | 1 | Malaysia | Myanmar |
| Boxing | 2 | New Zealand | Peru |
| Boxing | 3 | Palau | Belgium |
+----------+---------+-------------+------------+
我搜索了数据透视样本,但似乎都使用了我认为不适用于我的情况的聚合函数。
这是我陷入困境的地方:
SELECT *
FROM
(
SELECT Category
,Country
,Ranking
,[Year]
FROM table1
) AS SourceTable PIVOT(<b><font color="red"> ?? </font></b> FOR [Year] IN ([2017], [2018])) AS PivotTable;
解决方案
我认为条件聚合是实现预期结果的最简单方法。
您可以对Category
和进行分组Ranking
,然后使用 case 语句计算 2017 和 2018 列,最后null
使用 删除值max
:
declare @tmp table ([Year] int, Country varchar(50), Ranking int, Category varchar(50))
insert into @tmp values
(2018, 'Ghana' ,1, 'Swimming')
,(2018, 'Sweden' ,2, 'Swimming')
,(2018, 'Costa Rica' ,3, 'Swimming')
,(2018, 'Jordan' ,1, 'Sprint')
,(2018, 'Thailand' ,2, 'Sprint')
,(2018, 'Finland' ,3, 'Sprint')
,(2018, 'Myanmar' ,1, 'Boxing')
,(2018, 'Peru' ,2, 'Boxing')
,(2018, 'Belgium' ,3, 'Boxing')
,(2017, 'Nigeria' ,1, 'Swimming')
,(2017, 'Philippines' ,2, 'Swimming')
,(2017, 'Haiti' ,3, 'Swimming')
,(2017, 'Netherlands' ,1, 'Sprint')
,(2017, 'Macedonia' ,2, 'Sprint')
,(2017, 'Kuwait' ,3, 'Sprint')
,(2017, 'Malaysia' ,1, 'Boxing')
,(2017, 'New Zealand' ,2, 'Boxing')
,(2017, 'Palau' ,3, 'Boxing')
select
Category
, Ranking
, max(case when [year] = 2017 then country else null end) as [2017]
, max(case when [year] = 2018 then country else null end) as [2018]
From @tmp
group by
Category, Ranking
order by
Category desc, Ranking
输出:
推荐阅读
- fotorama - Fotorama:如何通过单击图像外部来取消全屏?
- java - 通过水平翻转原始图像来写入图像
- swift - 我想使用 SnapKit 将顶部 UIView 放置在 UITableView 之上
- c - 如何通过包含指向结构的指针的数组元素访问和修改在结构内声明的指针类型变量?
- python - 如何在不同的 Anaconda python 环境中共享站点包?
- javascript - 如何在给定的序列中找到字符串并将整个序列复制到另一个文本字段?
- google-apps-script - Google App Scripts 在时间执行配额中将什么视为“脚本”?
- reactjs - 在 timeOut 上反应重定向页面
- git - 在推送时,我收到“被合并覆盖”错误。我相信这是由更新后的钩子引起的。我可以绕过吗?
- excel - excel中macros-vba的文件大小限制?