【问题标题】:SQL Maybe Pivot? But I need actual value not numberSQL 也许枢轴?但我需要实际价值而不是数字
【发布时间】:2013-06-01 13:49:37
【问题描述】:

我想将“锁定”或“可编辑”的所有列名放入每个字段名的“可见者”字段中。有数百列,所以我正在寻找一种自动化的方式来做到这一点。

EG:

Field Name                   visible by   Business Development   VC Panel          Admin
Certification_Complete__c                   Hidden                 Lock             Editable
Certification_Status__c                     Hidden                 Hidden           Editable    

收件人:

Field Name                  visible by     Business Development    VC Panel        Admin
Certification_Complete__c  **VC Panel,Admin**   Hidden             Lock            Editable
Certification_Status__c     **Admin**           Hidden             Hidden          Editable

非常感谢

【问题讨论】:

  • 你用的是什么版本的sql server?

标签: sql sql-server tsql pivot pivot-table


【解决方案1】:

您的表结构是获得此结果的问题的一部分。理想情况下,您应该考虑将表重组为更规范化的结构。

您可以将结构更改为类似于以下内容:

CREATE TABLE certs
(
  [cert_id] int, 
  [FieldName] varchar(25)
);

INSERT INTO certs ([cert_id], [FieldName])
VALUES (1, 'Certification_Complete__c'),
    (2, 'Certification_Status__c');

CREATE TABLE permissions
(
  [permission_id] int, 
  [permissionName] varchar(20)
);

INSERT INTO permissions ([permission_id], [permissionName])
VALUES (1, 'Business Development'),
    (2, 'VC Panel'),
    (3, 'Admin');

CREATE TABLE certs_permissions
(
  [cert_id] int, 
  [permission_id] int, 
  [permission_type] varchar(8)
);

INSERT INTO certs_permissions ([cert_id], [permission_id], [permission_type])
VALUES
    (1, 1, 'Hidden'),
    (1, 2, 'Lock'),
    (1, 3, 'Editable'),
    (2, 1, 'Hidden'),
    (2, 2, 'Hidden'),
    (2, 3, 'Editable');

然后您可以通过连接表并使用 PIVOT 函数将行转换为列来获得结果。代码将与此类似:

;with cte as
(
  select c.cert_id, c.fieldname, p.permissionName, 
    cp.permission_type
  from certs c
  inner join certs_permissions cp
    on c.cert_id = cp.cert_id
  inner join permissions p
    on cp.permission_id = p.permission_id
) 
select fieldname,
  visibleby, 
  [Business Development], 
  [VC Panel],
  [Admin]
from
(
  select c1.fieldname,
    STUFF(
         (SELECT ', ' + cast(t.permissionName as varchar(50))
          FROM cte t
          where c1.fieldname = t.fieldname
            and t.permission_type in ('Lock', 'Editable')
          FOR XML PATH (''))
          , 1, 1, '')  AS [visibleby],
    c1.permissionname,
    c1.permission_type
  from cte c1
) d
pivot
(
  max(permission_type)
  for permissionname in ([Business Development], [VC Panel],
                          [Admin])
) piv

SQL Fiddle with Demo。这给出了一个结果:

|                 FIELDNAME |        VISIBLEBY | BUSINESS DEVELOPMENT | VC PANEL |    ADMIN |
---------------------------------------------------------------------------------------------
|   Certification_Status__c |            Admin |               Hidden |   Hidden | Editable |
| Certification_Complete__c |  VC Panel, Admin |               Hidden |     Lock | Editable |

如果您不想硬编码所有列值,您可以更改上面的脚本以轻松实现动态 SQL 以生成要执行的查询字符串。

如果您无法修复您的数据库结构,那么我建议您分两步进行。使用动态 SQL 来规范化您当前的数据库结构,以便您可以轻松地获得以逗号分隔的 visible_by 值列表。当您使用 UNPIVOT 函数时,您可以将数据扔到一个临时表中,该表可用于获取逗号分隔的列表。代码将与此类似:

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

select @colsUnpivot = STUFF((SELECT distinct ','+ quotename(c.column_name)
                   from INFORMATION_SCHEMA.COLUMNS as C
                   where (TABLE_NAME = 'yt') and
                      c.column_name not in ('Field Name', 'visible by')
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query 
  = 'select [Field Name], [visible by], colList, value
     into temp
     from yt
     unpivot
     (
       value
       for colList in ('+ @colsunpivot +')
     ) u'

exec(@query);

select distinct 
  t.[field name], 
  STUFF(
         (SELECT ', ' + cast(t2.colList as varchar(50))
          FROM temp t2
          where t.[Field Name] = t2.[Field Name]
            and t2.value in ('Lock', 'Editable')
          FOR XML PATH (''))
          , 1, 1, '')  AS [visible by],
  t.[Business Development],
  t.[VC Panel], 
  t.[Admin]
from yt t;

drop table temp;

SQL Fiddle with Demo

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-22
    • 1970-01-01
    • 2019-04-04
    • 2016-06-16
    • 1970-01-01
    • 1970-01-01
    • 2013-02-12
    相关资源
    最近更新 更多