2013-06-05 24 views
0

我想將所有列名稱的「鎖定」或「可編輯」放入「Visible by」字段中,用於每個字段名稱。有數百列,所以我正在尋找一種自動化的方式來做到這一點。SQL也許Pivot?但我需要的實際價值不是數字

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 

非常感謝

+0

? – Taryn

+0

2012免費版 – Kric

回答

3

你的表結構的問題得到這樣的結果的一部分。理想情況下,您應該考慮將您的表格重構爲更加標準化的結構。

你可以改變結構類似於此:

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'); 

然後,你可以通過連接表,並使用旋轉功能對行轉換成列得到的結果。代碼將與此類似:

;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您正在使用什麼版本的SQL Server

+0

感謝您的幫助:D – Kric

相關問題