在SQL Server中动态地将多个行组合成多个列

cha*_*abu 15 sql sql-server rows multiple-columns

我有一个大型数据库表,我需要使用Microsoft SQL Server动态执行下面的操作.

从这样的结果:

 badge   |   name   |   Job   |   KDA   |   Match 
 - - - - - - - - - - - - - - - -
 T996    |  Darrien |   AP    |   3.0   |   20
 T996    |  Darrien |   ADC   |   2.8   |   16
 T996    |  Darrien |   TOP   |   5.0   |   120
Run Code Online (Sandbox Code Playgroud)

使用SQL得到这样的结果:

badge   |   name   |  AP_KDA | AP_Match | ADC_KDA | ADC_Match | TOP_KDA | TOP_Match 
- - - - - - - - -
T996    |  Darrien |   3.0   |   20     |  2.8    |   16      |   5.0   |  120      
Run Code Online (Sandbox Code Playgroud)

即使有30行,它也会组合成一行60列.

我目前能够通过硬编码(参见下面的示例)来实现,但不是动态的.

Select badge,name,
(
 SELECT max(KDA)
 FROM table
 WHERE (h.badge = badge) AND (h.name = name) 
 AND (Job = 'AP')
) AP_KDA,
(
 SELECT max(Match)
 FROM table
 WHERE (h.badge = badge) AND (h.name = name) 
 AND (Job = 'AP')
) AP_Match,
(
 SELECT max(KDA)
 FROM table
 WHERE (h.badge = badge) AND (h.name = name) 
 AND (Job = 'ADC')
) ADC_KDA,
(
 SELECT max(Match)
 FROM table
 WHERE (h.badge = badge) AND (h.name = name) 
 AND (Job = 'ADC')
) ADC_Match,
(
 SELECT max(KDA)
 FROM table
 WHERE (h.badge = badge) AND (h.name = name) 
 AND (Job = 'TOP')
) TOP_KDA,
(
 SELECT max(Match)
 FROM table
 WHERE (h.badge = badge) AND (h.name = name) 
 AND (Job = 'TOP')
) TOP_Match
from table h
Run Code Online (Sandbox Code Playgroud)

我需要一个MSSQL语句,允许我将多行组合成一行.列3(Job)内容将与列4和5标题(KDAMatch)组合,并成为新列.

所以,如果有6倍不同的值Job(比如Job1通过Job6),那么结果将有12列,如:Job1_KDA,Job1_Match,Job2_KDA,Job2_Match,等,由徽章和名称分组.

我需要一个声明,它可以遍历第3列数据,因此我不需要硬编码(对每个可能的Job值重复查询)或使用临时表.

Rom*_*kij 10

我会用动态sql来做,但这是(http://sqlfiddle.com/#!6/a63a6/1/0)PIVOT解决方案:

SELECT badge, name, [AP_KDa], [AP_Match], [ADC_KDA],[ADC_Match],[TOP_KDA],[TOP_Match] FROM
(
SELECT badge, name, col, val FROM(
 SELECT *, Job+'_KDA' as Col, KDA as Val FROM @T 
 UNION
 SELECT *, Job+'_Match' as Col,Match as Val  FROM @T
) t
) tt
PIVOT ( max(val) for Col in ([AP_KDa], [AP_Match], [ADC_KDA],[ADC_Match],[TOP_KDA],[TOP_Match]) ) AS pvt
Run Code Online (Sandbox Code Playgroud)

奖励:这可以将PIVOT与动态SQL结合起来(http://sqlfiddle.com/#!6/a63a6/7/0),我更愿意做到更简单,没有PIVOT,但这只是很好的锻炼我 :

SELECT badge, name, cast(Job+'_KDA' as nvarchar(128)) as Col, KDA as Val INTO #Temp1 FROM Temp 
INSERT INTO #Temp1 SELECT badge, name, Job+'_Match' as Col, Match as Val FROM Temp

DECLARE @columns nvarchar(max)
SELECT @columns = COALESCE(@columns + ', ', '') + Col FROM #Temp1 GROUP BY Col

DECLARE @sql nvarchar(max) = 'SELECT badge, name, '+@columns+' FROM #Temp1 PIVOT ( max(val) for Col in ('+@columns+') ) AS pvt'
exec (@sql)

DROP TABLE #Temp1
Run Code Online (Sandbox Code Playgroud)