【问题标题】:How to pivot in SQL如何在 SQL 中进行数据透视
【发布时间】:2009-09-24 18:09:49
【问题描述】:

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

我的 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

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

【问题讨论】:

标签: sql sql-server-2005 pivot


【解决方案1】:

您是否阅读过 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;

我没有测试过以上,只是基于文档。这可能会让你开始。

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

【讨论】:

    【解决方案2】:

    试试这个:

    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
    

    经过测试。它给出了您想要的相同结果。

    【讨论】:

      【解决方案3】:

      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;
      

      【讨论】:

      • 您能否提供一个示例或阅读材料的链接。谢谢
      • 我添加了代码,但无法按客户分组。请问还有人吗?我花了足够的时间。
      猜你喜欢
      • 2021-03-10
      • 1970-01-01
      • 2011-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-23
      • 2022-08-18
      相关资源
      最近更新 更多