SQL列出缺少的项或无效的项

时间:2011-11-01 21:09:36

标签: sql

我有一个用户列表和一个角色列表。 我想提取用户应该拥有但不具备的角色报告以及他们确实拥有但不应该拥有的角色。 例如

User,   Dept,  Role
Jane, Manager, Add
Jane, Manager, Modify
Fred, Clerk, Modify
Fred, Clerk, Inquire

Dept, Task
Manager, Add
Manager, Modify
Manager, Delete
Manager, Inquire

Clerk, Inquire
Clerk, Add

我的查询应该表明Jane缺少删除和查询,Fred不应该修改。 目前,当我说出经理的任务<>之类的东西时,我会收到很多重复的内容。角色的任务包括Add<>等记录。修改

任何帮助将不胜感激

4 个答案:

答案 0 :(得分:1)

我对您的问题和数据的直接推断是您的表格被错误设计,允许模糊和错误(缺少或不合理授予权限),而不应该没有。

然而,使用你拥有的东西:

缺少特权(“角色”)

   SELECT d.User, d.Dept, d."Should Have" as "Missing"
     FROM (   SELECT DISTINCT udr.User, udr.Dept, dt.Task AS "Should Have"
                FROM UserDeptRole udr
           LEFT JOIN DeptTask dt
                     ON udr.Dept = dt.Dept) d
LEFT JOIN UserDeptRole udr2
          ON udr2.Dept = d.Dept AND udr2.Role = d."Should Have"
    WHERE udr2.Role is NULL;

输出:

+------+---------+---------+
| User | Dept    | Missing |
+------+---------+---------+
| Jane | Manager | Inquire |
| Jane | Manager | Delete  |
| Fred | Clerk   | Add     |
+------+---------+---------+

特权授权不当(“角色”)

   SELECT DISTINCT udr.User, udr.Role AS "Improper"
     FROM UserDeptRole udr
LEFT JOIN DeptTask dt
          ON udr.Dept = dt.Dept AND udr.Role = dt.Task
    WHERE dt.Task IS NULL

输出:

+------+----------+
| User | Improper |
+------+----------+
| Fred | Modify   |
+------+----------+

更好的问题

我鼓励您在单独的问题中询问SO社区如何重构您的架构以避免这种情况(缺少或不正确的角色)。

答案 1 :(得分:1)

标准SQL-99,在SQL Server 2008 R2上测试:

WITH ImpliedUserRoles
     AS
     (
      SELECT u."User", d.Dept, d.Task
        FROM UserRoles u
             INNER JOIN DeptTasks d
                ON u.Dept = d.Dept
     )
SELECT *, 'omission' AS role_error
  FROM ImpliedUserRoles
EXCEPT
SELECT *, 'omission' AS role_error
  FROM UserRoles
UNION
SELECT *, 'inclusion' AS role_error
  FROM UserRoles
EXCEPT
SELECT *, 'inclusion' AS role_error
  FROM ImpliedUserRoles;

答案 2 :(得分:0)

从您的用户表开始,左外连接到Dept上的角色表 - >部门和角色 - >任务。这样,如果用户不应该拥有该权限,它将返回null。

样品:

select u.User, case when d.Role is null then 0 else 1 end as Allowed
from User as U
left outer join Role as d
on U.Dept = d.Dept and U.Role = d.Task

答案 3 :(得分:0)

以下查询在大型数据集上无效!

您可以通过交叉联接确定所有可能性,然后使用正确的联接,只关心那些缺失的可能性。

(下面是带有表示示例数据的表变量的T-SQL)

select allTasks.[User], allTasks.[Dept], allTasks.Task as MissingTask
from @users u
    right outer join (
        select u.[User], d.Dept, d.Task
        from @depts d
            cross join (select distinct [User], Dept as [Dept] from @users) u
        where d.Dept = u.Dept) allTasks on allTasks.[User] = u.[User] and allTasks.Dept = u.Dept and allTasks.Task = u.Role
where u.[User] is null

结果:

User       Dept       MissingTask
---------- ---------- -----------
Fred       Clerk      Add
Jane       Manager    Delete
Jane       Manager    Inquire

(3 row(s) affected)

然后,此查询将查找具有他们可能不应该执行的任务的行:

select u.[User], u.Dept, u.Role as ExtraRole
from @users u
    left outer join @depts d on d.Task = u.Role and d.Dept = u.Dept
where d.Dept is null

结果:

User       Dept       ExtraRole
---------- ---------- ----------
Fred       Clerk      Modify

(1 row(s) affected)