我有这样的桌子…
LEVEL Action Date User -------------------------------------------------- 1 Approve 01/01/2013 User1 2 Approve 02/01/2013 User2 3 Rejected 03/01/2013 User3 1 Approve 04/01/2013 User1 2 Approve 05/01/2013 User2 3 Approve 06/01/2013 User3 . . . . . . . . . . . .
我想要这个…
使用PIVOT可以做到吗?
LEVEL1 - User 1 LEVEL2 - User 2 LEVEL3 - User 3 --------------------------------------------------------------------------- 01/01/2013 - Approve 02/01/2013 - Approve 03/01/2013 - Rejected 04/01/2013 - Approve 05/01/2013 - Approve 06/01/2013 - Approve . . . . . .
注意:级别数是动态的。 例如,完全批准一项可以是5级,6级等。因此,数据透视表中的列数是动态的。
是的,可以使用PIVOT函数完成此操作,我首先建议您查看查询的硬编码版本,以便在移至动态版本的查询之前可以查看查询的编写方式。
静态版本将类似于以下内容:
select [Level1 - User1], [Level2 - User2], [Level3 - User3] from ( select 'Level'+cast(level as varchar(1)) + ' - '+ [user] col, convert(varchar(10), date, 101) +' - '+ action value, row_number() over(partition by level order by [user], date) rn from yt ) d pivot ( max(value) for col in ([Level1 - User1], [Level2 - User2], [Level3 - User3]) ) piv;
请参阅带有演示的SQL Fiddle。您会注意到,levelanduser列被串联以创建新列,而dateand和action被串联以为每个列创建值。我还添加了row_number()一个为每一行创建一个唯一值,当您在PIVOT中应用聚合函数时,这一点很重要。如果您不使用它,那么结果将只有一行。
level
user
date
action
row_number()
由于您现在有了工作版本,因此可以轻松将其转换为动态版本:
DECLARE @cols AS NVARCHAR(MAX), @query AS NVARCHAR(MAX) select @cols = STUFF((SELECT distinct ',' + QUOTENAME('Level'+cast(level as varchar(1)) + ' - '+ [user]) from yt FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'') set @query = 'SELECT ' + @cols + ' from ( select ''Level''+cast(level as varchar(1)) + '' - ''+ [user] col, convert(varchar(10), date, 101) +'' - ''+ action value, row_number() over(partition by level order by [user], date) rn from yt ) x pivot ( max(value) for col in (' + @cols + ') ) p ' execute(@query);
请参阅带有演示的SQL Fiddle。两者的结果是:
| LEVEL1 - USER1 | LEVEL2 - USER2 | LEVEL3 - USER3 | ----------------------------------------------------------------------- | 01/01/2013 - Approve | 02/01/2013 - Approve | 03/01/2013 - Rejected | | 04/01/2013 - Approve | 05/01/2013 - Approve | 06/01/2013 - Approve |