多个案例中的子句

时间:2017-02-12 19:52:08

标签: sql-server where-clause

我在SQL中有一个安全表,2列是有价值的,列可以指示以下任何信息,每个用户可能存在选项L或D的多个条目,值列中的值,如果是L或者D表示用户可以访问或不访问的仓库列表,类似All表示用户可以访问所有仓库,None表示没有仓库访问。

Option | Value
---------------
A      | All
N      | None
L      | xyz (Allowed value)
D      | xyz (Denied Value)

我的问题在于SQL中的WHERE子句,我需要为所有4个场景提供配置,到目前为止我只能为4个场景中的3个配置,查看我的最后一个句子我需要在IN和NOT之间切换IN取决于选项。

WHERE 
  (CASE WHEN (SELECT TOP(1) Value FROM [AllowDisallowNone] ('demo1', 'ARBranches')) = 'All' 
              THEN 'All'  END != Branch 
  OR
  CASE WHEN (SELECT TOP(1) Value FROM [AllowDisallowNone] ('demo1', 'ARBranches')) = 'None' 
              THEN 'None' END = Branch 
  OR 
  Branch IN  (SELECT  Value FROM [AllowDisallowNone] ('demo1', 'ARBranches')))

有没有关于如何更有效地做这件事的建议?

关于这两个表的更多细节:

安全表如下所示:

SELECT [Operator]
,[Type]
,[TypeOption]
,[Value]
FROM [_OperatorAccess]
WHERE [Type] = 'ARBranches'

安全表数据:

Security Table results

请记住,对于允许的分支列表类似于TypeOption = A,可能会有用户使用TypeOption = D作为拒绝分支列表。

我需要过滤我的分支表查询,以便只显示用户有权访问的分支。如果我在4个单独的查询中拆分它,它将是这样的:

For TypeOption = A (All Records)
Select Invoice, Branch, InvDate FROM Branches  (No Where Clause necessary, because user have access to all Branches)

For TypeOption = N (No Records)
Select Invoice, Branch, InvDate FROM Branches WHERE Branch = '' (No Branches will be returned, becuase my Branch field cannot be null or empty.) 

For TypeOption = L (List of allowed branches)
Select Invoice, Branch, InvDate FROM Branches WHERE Branch IN (Select Value FROM _OperatorAccess WHERE Operator = 'RWOL' AND Type = 'ARBranches')

For TypeOption = D (List of denied branches)
Select Invoice, Branch, InvDate FROM Branches WHERE Branch NOT IN (Select Value FROM _OperatorAccess WHERE Operator = 'RWOL' AND Type = 'ARBranches')

我希望这更有意义。

1 个答案:

答案 0 :(得分:0)

将子查询更改为EXISTS子句:

SELECT *
FROM my_existing_query q
WHERE EXISTS (

    SELECT 1
    FROM [AllowDisallowNone] ('demo1', 'ARBranches')
    WHERE
    -- All warehouses permitted, or specific warehouse permitted
       (Value = 'All' AND Option = 'A')
    OR (Value = q.Branch AND Option = 'L')

    -- Deny permissions should override Allow permissions
    EXCEPT

    SELECT 1
    FROM [AllowDisallowNone] ('demo1', 'ARBranches')
    WHERE
    -- No warehouses permitted
       (Value = 'None' AND Option = 'N')
    OR (Value = q.Branch AND Option = 'D')
)