如何在SQL中进行透视

时间:2009-09-24 18:09:50

标签: sql sql-server-2005 pivot

我不确定这是否会被称为旋转。

我的SQL 2005表 [CustromerRoles] 中的数据是这样的:

CustId  RoleId
2        4
2        3
3        4
4        1
4        2

[角色] 表:

RoleId  Role
1        Admin
2        Manager
3        Support
4        Assistant

我想创建一个视图:

SELECT * FROM [MYVIEW]会给我以下数据:

1& 0将是位,以便我可以在UI显示屏上显示带有复选框的网格。

CustId  Admin Manager Support Assistant
2         0     0       1        1
3         0     0       0        1
4         1     1       0        0

到目前为止,我不知道该怎么做。

3 个答案:

答案 0 :(得分:6)

您是否阅读过Microsoft SQL Server 2005中PIVOT的文档?

SELECT CustId, 
  [1] AS Admin,
  [2] AS Manager,
  [3] AS Support,
  [4] AS Assistant
FROM (SELECT c.CustId, r.RoleId
FROM CustomerRoles c JOIN Roles r USING (RoleId)) AS s
PIVOT (
 COUNT(CustId)
 FOR RoleId IN ([1], [2], [3], [4])
) AS pvt
ORDER BY CustId;

我没有测试过上面的内容,只是基于doc。这可能会让你开始。

似乎没有办法动态生成列。你必须对它们进行硬编码。

答案 1 :(得分:4)

试试这个:

SELECT 
    CustId, 
    SUM(ISNULL(Admin,0)) AS Admin, 
    SUM(ISNULL(Manager,0)) AS Manager, 
    SUM(ISNULL(Support,0)) AS Support, 
    SUM(ISNULL(Assistant,0)) AS Assistant
FROM
(
    SELECT cr.CustId, cr.RoleId, Role, 1 AS a
    FROM CustromerRoles cr
    INNER JOIN Roles r ON cr.RoleId = r.RoleId
) up
PIVOT (MAX(a) FOR Role IN (Admin, Manager, Support, Assistant)) AS pvt
GROUP BY CustId

测试。它给出了你想要的相同结果。

答案 2 :(得分:2)

PIVOT的缺点是必须知道列,因为您必须在查询中提供ID。您可以使用动态SQL解决此问题,即在您的情况下根据Roles表中的单独查询结果动态生成PIVOT查询,然后执行结果。这可以在存储过程中轻松完成。

示例:

CREATE TABLE #CustomerRole ([CustId] int, [RoleId] int);
INSERT INTO #CustomerRole values (2, 4);
INSERT INTO #CustomerRole values (2, 3);
INSERT INTO #CustomerRole values (3, 4);
INSERT INTO #CustomerRole values (4, 1);
INSERT INTO #CustomerRole values (4, 2);

CREATE TABLE #Role ([Id] int, [Role] varchar(20));
INSERT INTO #Role values (1, 'Admin');
INSERT INTO #Role values (2, 'Manager');
INSERT INTO #Role values (3, 'Support');
INSERT INTO #Role values (4, 'Assistant');

DECLARE @RoleList nvarchar(MAX)
SELECT @RoleList = COALESCE(@RoleList + ',[' + [Role] + ']',
 '[' + [Role] + ']') 
    FROM #Role;

DECLARE @SQL Nvarchar(max);
SET @SQL = 'SELECT 
                [CustId] '  + 
                ISNULL(', ' + @RoleList , '') + ' 
                FROM #CustomerRole custrole
                inner join #Role as r
                on r.[Id] = custrole.[RoleId]
            PIVOT (count([Id]) for [Role] IN 
                (' + ISNULL(@RoleList, '[No role]') +
                 ')) as pvt;' 

EXEC sp_executesql @SQL;

drop table #Role;
drop table #CustomerRole;