2014-03-05 3 views
0

사용자에게 특정 항목에 대한 액세스 권한을 정의하는 권한 시스템이 있습니다.SQL 쿼리 및 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 인수의 열 이름.

나는 당신이 쿼리에 대한 UNPIVOT을 사용할 필요가 없습니다 Sqlfiddle

답변

3

놀 예를 만들었습니다. UNPIVOT은 여러 열을 여러 행으로 변환하는 데 사용됩니다. 항목을 열로 바꾸려면 PIVOT 함수 만 적용하면됩니다.

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 참조 : 내가 먼저 새 열 머리글을 만들 row_number() 같은 윈도우 기능을 사용하는 것이 좋습니다 것

는 다음 PIVOT 기능을 적용 할 수 있습니다.

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

감사를 참조하십시오; 당신이 값을 알 수없는 번호가있는 경우 다음 쿼리는 동적 SQL을 사용해야합니다 항목 이름을 열 이름으로 어떻게 사용할 수 있습니까? 즉, "항목 1, 항목 2"대신 "Blue Item, Red Item" – dvdmn

+0

@dvdnhm 여전히 동일한 프로세스를 사용할 수 있지만'rownumber() '를 사용하여 열 목록을 생성하는 대신에 다음과 같은 값을 사용합니다. 너의 칼럼. – Taryn