在 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;

我认为条件聚合是实现预期结果的最简单方法。

您可以对 CategoryRanking 进行分组,然后使用 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 

输出: