1

我在 SQL Server 2008 数据库中有 3 个表。第一个表包含用户名,第二个包含权限,最后一个链接前两个表:

用户ID整数,NAMEvarchar(20));

PRIVSID整数,NAMEvarchar(50));

USERS_PRIVSUSERID整数,PRIVID整数);

例如,USERS 表有以下内容:

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

这可以使用枢轴功能吗?

4

3 回答 3

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
于 2013-09-25T21:30:30.850 回答
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
于 2013-09-25T21:35:08.703 回答
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);

我从这里借用了 XML 的东西Dynamic Pivot Columns in SQL Server

于 2013-09-25T21:38:43.293 回答