在 Sql 服务器中将行转换为列
Pivot rows into columns in Sql Server
我有一个示例 table,看起来像这样:
+------+-------------+---------+----------+
| 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 列,最后使用 max
:[=16 删除 null
值=]
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
输出:
我有一个示例 table,看起来像这样:
+------+-------------+---------+----------+
| 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 列,最后使用 max
:[=16 删除 null
值=]
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
输出: