我有一张这样的桌子......
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级等完全批准一个项目。因此,Pivoted表中的列数是动态的。
答案 0 :(得分:7)
是的,这可以使用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 with Demo。您会注意到level
和user
列连接在一起以创建新列,并且date
和action
被连接起来为每列创建值。我还添加了一个row_number()
来为每行创建一个唯一值,这在PIVOT中应用聚合函数时非常重要。如果你不使用它,那么结果只会得到一行。
由于您现在有一个工作版本,因此可以轻松地将其转换为动态版本:
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 with Demo。两者的结果是:
| 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 |