1

SQL FIDDLE 演示在这里

我有这种表结构:

    CREATE TABLE Users
    
            ([UserId] int, 
            [IdDepartment] int);
    
    INSERT INTO Users
        ([UserId], [IdDepartment])
    VALUES
        (1, 5),
        (2, 0),
        (3, -1),
        (4, 0),
        (5, -1),
        (6, 0);
    
    CREATE TABLE Department
        ([IdDepartment] int, [Name] varchar(23), [IdUser] int);
        
    INSERT INTO Department
        ([IdDepartment], [Name], [IdUser])
    VALUES
        (1, 'Sales', 3),
        (2, 'Finance', null ),
        (3, 'Accounting' , 5),
        (4, 'IT' ,3),
        (5, 'Secretary',null),
        (6, 'Sport',3);

我想用这个结果查询:在用户表中,如果 IdDepartment 为 0,则表示用户是管理员,因此他可以查看所有部门。如果用户在 idpartment 中有 -1,则意味着用户可以访问有限的部门,所以在这种情况下,我对 Department 表进行内部连接以获取该部门的列表。最后一种情况是,如果用户在用户表中的 idDepartament 有一个不同于 0 和 -1 的编号,则表示该用户只能访问该部门。

我试图做类似的事情,但它的结构不是很好:

select
    case idDepartment
       when  0 then (select Name from Department)
       when -1 then (select Name from Department where IdUser = 3)
       else         (select Name from Department 
                      inner join Users on Department.idDepartment = Users.Department         
                      where Users.UserId = 3)
    end
from 
    Department
where 
    IdUser = 3

我怎样才能做到这一点?谢谢。

我为我想要获得的内容添加了一个示例:

 -For the user that has the userid (1) -->

    Department Name
    ---------------
    Secretary




-For the user that has the userid (2) -->
    
    Department Name
    ---------------
    Sales
    Finance
    Accounting
    IT
    Secretary
    Sport




-For the user that has the userid (3) -->
    
    Department Name
    ---------------
    Sales
    IT
    Sports
4

4 回答 4

2

你不能在 a 中做这样的事情SELECT CASE,最好的选择是引入一些逻辑

DECLARE @IdUser INT = 3
DECLARE @userDepartment INT
SELECT @userDepartment = IdDepartment
FROM Users
WHERE UserId = @IdUser

IF @userDepartment = 0
BEGIN
    SELECT Name FROM Department
END
ELSE IF @userDepartment = -1
BEGIN
   SELECT Name FROM Department WHERE IdUser = @IdUser
END
ELSE
BEGIN
    SELECT Name FROM Department 
    INNER JOIN Users 
       ON Department.idDepartment = Users.IdDepartment 
    WHERE Users.UserId = @IdUser
END

顺便说一句,您已经找到了为什么您的结构不理想。如果您在用户和部门之间有一个联结表,您可以使用更简单的查询对您已有的任何组合进行建模(以联结表中的大量行为代价)

于 2016-03-30T14:39:29.567 回答
2

您的示例代码有点混乱,但感觉就像您正在寻找这样的东西:

declare @id_user int = 3

select d.IdDepartment, d.Name
from Department d
where exists
  (
    select 1
    from Users u
    where u.[UserId] = @id_user
      and u.IdDepartment in (0, d.IdDepartment)
  )
  or d.[IdUser] = @id_user

实现:

  • 如果表格IdUser中的内容与给定Department的相同@id_user- 他肯定可以访问该部门
  • IdDep否则,如果该用户的值0等于或等于相应的部门 ID,则该用户有权访问部门

但是您的权限/安全模型闻起来不好,而且绝对不可扩展。你最好发明另一个实体(表)来存储允许的元组:(IdUser,IdDepartment)。在这种情况下,Select 语句看起来会更加清晰。

于 2016-03-30T14:53:03.837 回答
1
  declare @IdUser int = 3;
  SELECT u.[UserId], d.Name 
  from Users u
  join Department d
        on   u.[IdDepartment] =  0 
        or ( u.[IdDepartment] = -1 and d.[IdUser]       = u.[UserId] )
        or ( u.[IdDepartment] >  0 and d.[IdDepartment] = u.[IdDepartment] )
   where u.[UserId] = @IdUser 
   order by u.[UserId], d.Name

userID 3 应该包括运动

于 2016-03-30T15:26:36.790 回答
-1

如果我从您的伪查询中了解您正在尝试做什么,您可以使用精心构造的 WHERE 子句来做到这一点:

case idDepartment
   when 0 then (select Name from Department)
   when -1 then (select Name from Department where IdUser = 3)
   else (select Name from Department inner join Users on     Department.idDepartment = Users.Department where Users.UserId = 3)
end

可以写成子选择:

(SELECT Name
 FROM Department
 LEFT OUTER JOIN Users
   on     Department.idDepartment = Users.Department
 WHERE idDepartment=0
 OR (idDepartment = -1 AND idUser = 3)
 OR (Users.UserId = 3)
)

当然,您必须将子选择与您的外部查询相关联。

于 2016-03-30T14:56:58.313 回答