2014-03-05 38 views
0

我有一個權限系統,用於定義用戶對特定項目的訪問權限。SQL Query&unpivot語法

我需要一個報告頁面來顯示成員及其對項目的訪問權限。

的表需要是這樣的:

+---------+--------+--------+------+--------+ 
| Members | Item 1 | Item 2 | .... | Item N | 
+---------+--------+--------+------+--------+ 
| Member1 | x | + | .... | + | 
+---------+--------+--------+------+--------+ 
| Member2 | + | x | .... | + | 
+---------+--------+--------+------+--------+ 

我有一個3表連接查詢上市的成員,他們可以訪問的項目,但我不能把它轉換成旋轉的語法。

Select members.id memberID, members.name memberName, items.name as item 
From members 
Left Join member_permission On memberID = members.id 
Left Join items On items.id = member_permission.itemID 

這是不工作的查詢,我有:

Select memberName, itemName 
From (
    select members.id, members.name, item.name as itemName 
    from members 
    Left Join member_permission On memberID = members.id 
    Left Join item On item.id = member_permission.itemID 
) p 
Unpivot 
(itemName For name IN (item.name)) as unp 

和錯誤我收到:在UNPIVOT操作衝突

列名「名」指定與現有UNPIVOT參數中的列名稱。

我創建了一個例子與Sqlfiddle

回答

3

打你不需要使用UNPIVOT此查詢。 UNPIVOT用於將多列轉換爲多行。您只需要應用PIVOT功能將您的項目變成列。

我首先建議使用像row_number()窗口函數來創建新的列標題,然後應用旋轉功能:

select id, name, Item1, Item2, Item3 
from 
(
    select members.id, members.name, items.name as item, 
    'item'+ 
     cast(row_number() over(partition by members.id 
          order by members.id) as varchar(10)) col 
    from members 
    Left Join member_permission 
    On memberID = members.id 
    Left Join items 
    On items.id = member_permission.itemID 
) d 
pivot 
(
    max(item) 
    for col in (Item1, Item2, Item3) 
) piv; 

SQL Fiddle with Demo。然後,如果你有一個未知的數值的查詢可能需要使用動態SQL:

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

select @cols = STUFF((SELECT ',' + QUOTENAME('item'+cast(seq as varchar(10))) 
        from 
        (
         select row_number() over(partition by memberid 
               order by memberid) seq 
         from member_permission 
        ) d 
        group by seq 
        order by seq 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query = N'SELECT id, name, ' + @cols + N' 
      from 
      (
       select members.id, members.name, items.name as item, 
       ''item''+ 
        cast(row_number() over(partition by members.id 
             order by members.id) as varchar(10)) col 
       from members 
       Left Join member_permission 
       On memberID = members.id 
       Left Join items 
       On items.id = member_permission.itemID 
      ) x 
      pivot 
      (
       max(item) 
       for col in (' + @cols + N') 
      ) p ' 

execute sp_executesql @query; 

SQL Fiddle with Demo

+0

感謝您的回答,一個一個細節;我怎樣才能使用項目名稱作爲列名?即:「藍色項目,紅色項目」而不是「項目1,項目2」 – dvdmn

+0

@dvdnhm您仍然可以使用相同的過程,但不是使用'rownumber()'生成列的列表,您可以使用你的專欄。 – Taryn