假设我的user_role
表包含user
和role
列。
| User | Role |
---------------
| 100 | 10 |
| 101 | 10 |
| 101 | 11 |
| 102 | 11 |
我想编写一个返回具有相同或较小角色的用户的查询。例如:
业务要求:假设用户X仅属于亚洲群组。因此X应该只对属于亚洲组的用户具有访问权限。但是说Y属于亚洲和欧洲组织。所以Y应该拥有属于以下用户的访问权限:
现在,X不应该访问Y的数据,因为X不属于Y所属的所有组。同样,说Z属于亚洲,欧洲和美洲。因此,Z应该访问X,Y和Z的所有数据,但反之则不然。
我的初始SQL:
select distinct(user) from user_role where role in
(select role from user_role where user=?);
以上查询返回所有共享至少一个公共群组而非所有公共群组的用户。
有人可以帮我一个SQL示例吗?
答案 0 :(得分:3)
这可以通过更少的努力来完成。这个想法是在特定用户的角色上保留连接角色,然后仅过滤那些在该特定用户的角色中找到所有角色的用户:
;with c as(select roleid from userroles where userid=100)
select r.userid from userroles r left join c on r.roleid = c.roleid
group by r.userid
having sum(case when c.roleid is null then 1 else 0 end) = 0
答案 1 :(得分:2)
试试这个:
-- Create a CTE that will help us know the number of roles any user have.
;WITH CTE (UserId, RoleId, NumberOfRoles)
AS (
SELECT T1.UserId, RoleId, NumberOfRoles
FROM UsersToRoles T1 INNER JOIN
(
-- Derived table is needed so that we can have
-- the user, he's roleId and he's number of roles in the CTE
SELECT UserId, COUNT(RoleId) As NumberOfRoles
FROM UsersToRoles
GROUP BY UserId
) T2 ON(T1.UserId = T2.UserId)
)
-- We join the CTE with itself on the RoleId to get only users that have the same roles,
-- and on the NumberOfRoles to ensure that the users we get back have at least the nomber of roles as the user we testing.
SELECT DISTINCT T1.UserId
FROM CTE T1
INNER JOIN CTE T2 ON(T1.RoleId = T2.RoleId AND T1.NumberOfRoles <= T2.NumberOfRoles)
WHERE T2.UserId = @UserId
Play with it yourself in this sql fiddle
CTE或Common Table Expressions是Sql Server 2008中引入的一个概念。基本上,你定义了一个select语句,你的sql的其余部分可以引用它,就像它是一个视图一样。
在这种情况下,您可以将此CTE写为视图,它会给您相同的结果。