通过sql server中的另一列将行转换为列

时间:2011-11-23 19:19:53

标签: sql sql-server pivot

我正在尝试转换此表

ID  TestID  Elapsed ActionID
===================================
1   1         16    a1
2   1         17    a2
3   1         13    a3  
4   1         14    a4
5   2         19    a1
6   2         21    a2
7   2         11    a3
8   2         22    a4

到此

TestID  a1  a2  a3  a4
======================================
1       16  17  13  14
2       19  21  11  22
这可能吗?

2 个答案:

答案 0 :(得分:1)

如果您使用的是SQL Server 2005(或更高版本),这里的查询是概念验证。享受:

--Proof of concept structure and data creation
create table #t (ID int, TestID int, Elapsed int, ActionID varchar(10))

insert into #t  (ID, TestID, Elapsed, ActionID) values
(1,   1,         16,    'a1'),
(2,   1,         17,    'a2'),
(3,   1,         13,    'a3'),
(4,   1,         14,    'a4'),
(5,   2,         19,    'a1'),
(6,   2,         21,    'a2'),
(7,   2,         11,    'a3'),
(8,   2,         22,    'a4');
--end of structure and data creating

--actual query starts here
DECLARE @cols VARCHAR(1000)
DECLARE @sqlquery VARCHAR(2000)

SELECT  @cols = STUFF(( SELECT distinct  ',' + QuoteName([ActionID])
                        FROM #t  FOR XML PATH('') ), 1, 1, '') 

SET @sqlquery = 'SELECT * FROM
      (SELECT TestID, Elapsed, ActionID
       FROM #t  ) base
       PIVOT (SUM(Elapsed) FOR [ActionID]
       IN (' + @cols + ')) AS finalpivot'

--Depending on your approach, you might want to use MAX instead of SUM. 
--That will depend on your business rules

EXECUTE ( @sqlquery )
--query ends here


--proof of concept cleanup
drop table #t;

无论您在ActionID中有多少不同的值,这都会有效。它使用PIVOT动态组装查询。使用动态列进行PIVOT的唯一方法是动态组合查询,这可以在SQL Server中完成。

其他例子:

答案 1 :(得分:1)

是的,如果每个testid只有一个操作ID

Ajoe提到的枢轴操作员,但我认为是传统的 语法更容易理解(如果不是很明显)。

您可以按testid对行进行分组,这样您就可以获得一行结果 每个testid。你选择的是每个组中的“max”,其中acitionid是某一个。或者是最小值,平均值或总和 - 这是 因为每组中只有一个项目。

 SELECT testid,
   MAX(CASE WHEN actionid = 'a1' THEN elapsed ELSE null END) AS a1,
   MAX(CASE WHEN actionid = 'a2' THEN elapsed ELSE null END) AS a2,
   MAX(CASE WHEN actionid = 'a3' THEN elapsed ELSE null END) AS a3,
   MAX(CASE WHEN actionid = 'a4' THEN elapsed ELSE null END) AS a4
FROM results
GROUP BY testid