2013-09-25 5 views
1

SQL Server 2008 데이터베이스에 3 개의 테이블이 있습니다. 첫 번째 테이블은 두 번째는 특권과 마지막 링크 처음 두 테이블을 포함하고, 사용자 이름을 포함SQL 쿼리에서 테이블 반환

USERS를 (ID 정수, NAME VARCHAR (20));

privs (ID 정수, NAME varchar (50));

USERS_PRIVS (USERID 정수, PRIVID 정수);

예를 들어

, 사용자 테이블이 다음

1, Adam 
2, Benjamin 
3, Chris 

privs 및 테이블이 있습니다

1, Add Invoice 
2, Edit Invoice 
3, Delete Invoice 

USERS_PRIVS 테이블이 있습니다 내가 찾고 있어요

1, 1 
1, 2 
1, 3 
2, 1 
2, 2 
3, 1 

을 방법은 다음과 같은 것을 반환하는 SQL 쿼리를 생성합니다 :

  Add Invoice Edit Invoice Delete Invoice 
Adam  Y    Y    Y 
Benjamin Y    Y    N 
Chris  Y    N    N 

피벗 기능을 사용하면 가능합니까?

+2

예에서 XML 물건을 빌려. 이 사이트와 웹 주위에는'PIVOT'의 예가 많이 있습니다. 너 뭐 해봤 니? –

+0

@JonofAllTrades : 다양한 피벗 제안을 시도했습니다. 내가 겪고있는 문제는 PRIVS 테이블에서 열 머리글을 얻는 것이고 아래의 모든 제안에 따라 SQL에서 하드 코딩하는 것입니다. – Caynadian

답변

1
SELECT Name, [Add Invoice],[Edit Invoice],[Delete Invoice] FROM 
(SELECT U.Name AS Name, P.Name AS PrivName FROM USERS_PRIVS UP 
    INNER JOIN Users U ON UP.UserID = U.id 
    INNER JOIN Privs P ON UP.PrivID = P.id) SB 
PIVOT(
count(SB.PrivName) 
FOR SB.PrivName in ([Add Invoice],[edit Invoice],[Delete Invoice])) AS Results 

편집 1 : 당신은 다음 몇 가지 동적 SQL을 사용해야합니다.

DECLARE @query AS NVARCHAR(MAX); 
DECLARE @privColumnNames AS NVARCHAR(MAX); 

select @privColumnNames = STUFF((SELECT distinct ',' + QUOTENAME(Name) 
            FROM PRIVS FOR XML PATH(''), TYPE 
           ).value('.', 'NVARCHAR(MAX)'), 1, 1, ''); 

SELECT @query = 
'SELECT * 
FROM 
(SELECT U.Name AS Name, P.Name AS PrivName FROM USERS_PRIVS UP 
    INNER JOIN Users U ON UP.UserID = U.id 
    INNER JOIN Privs P ON UP.PrivID = P.id) SB 
PIVOT(
count(SB.PrivName) 
FOR SB.PrivName in (' + @privColumnNames + ')) AS Results '; 

execute(@query); 

는 여기 Dynamic Pivot Columns in SQL Server

+0

이것은 작동하지만 각 열 이름을 열 머리글로 하드 코딩하는 것을 피하기를 희망했습니다. 테이블의 권한을 기반으로 열 이름을 동적으로 설정하는 방법이 있습니까? – Caynadian

+0

@Caynadian는 Edit 1을 참조하십시오. 이것은 동적 SQL을 사용하여 Privs 테이블에서 열의 목록을 가져옵니다. – Josh

+0

그건 멋져요! 감사! – Caynadian

1

여기에 데모가 SqlFiddle입니다.

with cl 
as (
select u.NAME , case when p.ID = 1 then 'Y' else 'N' end 'Add Invoice', 
case when p.ID = 2 then 'Y' else 'N' end 'Edit Invoice', 
case when p.ID = 3 then 'Y' else 'N' end 'Delete Invoice' 
from USERS u inner join USERS_PRIVS up on u.ID = up.USERID 
inner join PRIVS p on up.PRIVID = p.ID 
) 

select NAME, MAX([Add Invoice]) 'Add Invoice', 
MAX([Edit Invoice]) 'Edit Invoice', 
MAX([Delete Invoice]) 'elete Invoice' 
from cl 
group by NAME 

여기에 데모가 SqlFiddle입니다.

select NAME , case when [Add Invoice] = 1 then 'Y' else 'N' end 'Add Invoice', 
case when [Edit Invoice] = 1 then 'Y' else 'N' end 'Edit Invoice', 
case when [Delete Invoice] = 1 then 'Y' else 'N' end 'Delete Invoice' 
from (
select u.NAME, p.NAME as pname 
from USERS u inner join USERS_PRIVS up on u.ID = up.USERID 
inner join PRIVS p on up.PRIVID = p.ID 
) p 
pivot(count(pname) for pname in ([Add Invoice], [Edit Invoice], [Delete Invoice])) as pvt 
+0

두 번째 스크립트는 작동하지만 각 권한 이름을 열 제목으로 하드 코딩하지 않으려했습니다. 테이블의 권한을 기반으로 열 이름을 동적으로 설정하는 방법이 있습니까? – Caynadian

1

이 시도 :

select 
    name, 
    CASE [1] WHEN 1 THEN 'Y' ELSE 'N' END as 'Add Invoice', 
    CASE [2] WHEN 1 THEN 'Y' ELSE 'N' END as 'Edit Invoice', 
    CASE [3] WHEN 1 THEN 'Y' ELSE 'N' END as 'Delete Invoice' 
from 
    (select name, userId, privid, 1 temp from users_privs join users on id = userid) as sourceTable 
    pivot(min(temp) for privid in ([1], [2], [3])) as pivotTable 
+0

이 방법이 효과적이지만 각 권한 이름을 열 머리글로 하드 코딩하지 않기를 바랬습니다. 테이블의 권한을 기반으로 열 이름을 동적으로 설정하는 방법이 있습니까? – Caynadian

관련 문제