我有表user_profile,模块,角色privilege_mapping
使用privilege_mapping表条目作为[ID,Module,privilege,userId,RoleID]
1 | Settings | true | NULL | 1
2 | Settings | false | 1 | 1
3 | About | true | NULL | 1
4 | DashBoard| true | NULL | 1
我要求某些用户的某些权限必须被覆盖(打开/关闭),而不是他们的角色权限.
对于eq:用户1具有角色ID 1.根据角色1设置被拒绝.但是我为用户启用了另一个被覆盖的条目.
应优先考虑用户权限.
所以应该是用户1的特权
2 | Settings | false | 1 | 1
3 | About | true | NULL | 1
4 | DashBoard | true | NULL | 1
我是sql查询的初学者.我怎样才能达到效果
任何帮助将不胜感激
这就是我到目前为止所做的.但现在它包含两行
;WITH prvCTE AS
(
-- Insert statements for procedure here
(
SELECT module_id, url, privilege, module_name
FROM [dbo].[UserProfile] U
INNER JOIN [dbo].[privilege_mapping] P ON p.user_id = u.id
INNER JOIN [dbo].[module] M ON p.module_id = M.id
WHERE U.id = @userID
EXCEPT
-- Insert statements for procedure here
SELECT module_id, url, privilege, module_name
FROM [dbo].[UserProfile] U
INNER JOIN [dbo].[role] R ON U.RoleID = R.RoleID
INNER JOIN [dbo].[privilege_mapping] P ON p.role_id = R.RoleID
INNER JOIN [dbo].[module] M ON p.module_id = M.id
WHERE U.id = @userID
)
UNION
SELECT module_id, url, privilege, module_name
FROM [dbo].[UserProfile] U
INNER JOIN [dbo].[role] R ON U.RoleID = R.RoleID
INNER JOIN [dbo].[privilege_mapping] P ON p.role_id = R.RoleID
INNER JOIN [dbo].[module] M ON p.module_id = M.id
WHERE U.id = @userID
)
SELECT *
FROM prvCTE
最佳答案 好.我认为你需要考虑3种不同的情况:
>用户存在,但用户没有UserPrivilege或RolePrivilege
>用户存在,用户同时具有UserPrivilege和RolePrivilege
>用户存在,并且有一个
要在单个查询中考虑所有3个,您需要几个子查询和几个外部联接.
SubQuery1:UserPrivileges
为了获得所有用户权限,我们提取:
SELECT * FROM [dbo].[privilege_mapping] WHERE user_id IS NOT NULL
SubQuery2:RolePrivileges
要获得所有ROLE权限,我们使用此查询:
SELECT * FROM [dbo].[privilege_mapping] WHERE user_id IS NULL
将它们全部拉到一起:COALESCE()
最后,要使用一个或另一个(取决于哪一个存在),我们使用COALESCE()语句.这种方式(我认为)我们可以在一个语句中完成整个选择:
SELECT module_id, url, privilege=COALESCE(UP.privilege,RP.privilege), module_name
FROM [dbo].[UserProfile] U
LEFT OUTER JOIN (SELECT * FROM [dbo].[privilege_mapping] WHERE user_id IS NOT NULL) UP ON UP.user_id = U.id
LEFT OUTER JOIN (SELECT * FROM [dbo].[privilege_mapping] WHERE user_id IS NULL) RP ON RP.role_id = U.role_id
LEFT OUTER JOIN [dbo].[module] M ON COALESCE(UP.module_id,RP.module_id)=M.id
WHERE U.id = @userID AND M.id IS NOT NULL
角色ID?
我从你的架构中遗漏了这个.我不知道如何告诉用户播放给定的“角色”我假设用户表中有一个role_id,但无法从问题中得知.所以 – 我补充说,作为我们加入的领域.
MODULE?
好.我没有完整的架构,所以我不确定该模块的最后左外连接是否正常.我有一种感觉,我们需要另一个where子句来摆脱NULL module_id(例如WHERE module_id IS NOT NULL).
请注意,我们从LEFT OUTER JOIN拉出的字段上的子句很棘手(因为如果编码不正确,它可能会将连接转换为INNER JOIN).
试试这个.看看我们有多接近,然后我们就可以调整.