SQL:将一行转换为一列(并在新列中包含列名)

Vel*_*rev 0 sql sql-server unpivot sql-server-2008-r2

我正忙着编写一个声明提供程序类,用于安全令牌服务.

从SQL Server 2008 R2数据库读取用户权限:

SELECT A, B, C, ..., X FROM Permissions WHERE UserId = @UserId
Run Code Online (Sandbox Code Playgroud)

会给我一行,例如:

A B C ... X
1 0 1     1
Run Code Online (Sandbox Code Playgroud)

在表单中包含这些数据要容易得多

Permission Value
A          1
B          0
C          1
...
X          1
Run Code Online (Sandbox Code Playgroud)

由于实际表包含几十列,我宁愿能够"动态"进行转置,而无需手动输入任何列名.

感觉像PIVOT/UNPIVOT函数和INFORMATION_SCHEMA.COLUMNS视图是我需要的,但我不知道该怎么做.

查询的任何想法会这样做?

PS.我想如果push推进,我只是将结果集粘贴在DataTable中并迭代代码中的列以生成用户声明,但我想知道上述方法是否可行首先:)

Tar*_*ryn 5

如果您没有UNPIVOT可用的功能(您没有指定RDBMS),那么您可以使用UNION ALL(请参阅SQL Fiddle with Demo):

select 'A' as Permission, A as Value
FROM Permissions
WHERE UserId = @UserId
UNION ALL
select 'B' as Permission, B as Value
FROM Permissions
WHERE UserId = @UserId
Run Code Online (Sandbox Code Playgroud)

如果你在sql-server中有一个未知数量的列,那么你可以使用动态sql,你的代码将类似于:

DECLARE @colsUnPivot AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

SET @colsUnPivot = stuff((select ','+C.name
         from sys.columns as C
         where C.object_id = object_id('Permissions')
            and C.name != 'UserId'
         for xml path('')), 1, 1, '')

set @query 
  = 'select permission, value
    from
    (
        select *
         from permissions
         where userid = '+@UserId+'
    ) x
     unpivot
     (
        value
        for permission in ('+ @colsunpivot +')
     ) u'

exec(@query)
Run Code Online (Sandbox Code Playgroud)

看看SQL Fiddle with Demo