Sql覆盖查询

我有表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).

试试这个.看看我们有多接近,然后我们就可以调整.

点赞