查询将未知行数转换为未知列数

时间:2012-06-04 16:20:20

标签: sql-server sql-server-2008 pivot crosstab

我一直在寻找几个小时的不同选项(PIVOT,CROSS JOIN等......)使用SQL Server 2008将未知数量的行转换为未知数量的列,我比以前更加迷失启动。

基本上我有3张桌子:

角色

|id| name|
| 1|role1|
| 2|role2|
| 3|role3|

动作

|id|  name |
| 1|action1|
| 2|action2|
| 3|action3|

RoleAction

|roleId| actionId|
|   1  |    1    |
|   1  |    2    |
|   2  |    1    |
|   3  |    2    |

无论如何构建一个查询或SP会将LEFT JOIN的结果转换为一个漂亮的“pivot”表,如下所示:

|actionId|actionName|role1|role2|role3|.....|role n|
|   1    | action1  |  1  |  1  |  0  |.....|   0  |
|   2    | action2  |  1  |  0  |  1  |.....|   0  |
|   3    | action3  |  0  |  0  |  0  |.....|   0  |
|   .    |    .     |  .  |  .  |  .  |.....|   .  |
|   .    |    .     |  .  |  .  |  .  |.....|   .  |
|   n    | action n |  0  |  0  |  0  |.....|   0  |

非常感谢你的帮助!

1 个答案:

答案 0 :(得分:1)

非常感谢Aaron让我走上正轨!

ALTER PROCEDURE dbo.RoleActionsPivot
AS

SET NOCOUNT ON

DECLARE @cols AS NVARCHAR(MAX), @query  AS NVARCHAR(MAX);

SELECT  Action.ActionId, Action.ActionName , Role.RoleId, Role.RoleName
INTO    #tmpRoleAction
FROM    Action LEFT JOIN RoleActions ON Action.ActionId = RoleAction.ActionId 
    LEFT JOIN Role ON RoleAction.RoleId = Role.RoleId

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(RoleName) 
            FROM #tmpRoleAction
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT ActionId, ActionName, ' + @cols + ' FROM

    (SELECT * FROM #tmpRoleAction) x

    PIVOT  ( max(RoleId) for RoleName in (' + @cols + ')) p '


execute(@query)