SQL如何基于逻辑JOIN进行过滤

时间:2017-02-15 23:33:25

标签: sql-server

我有一个关于联接的查询:

....
JOIN 
    Permission up ON up.PermissionID = c.PermissionID 
                  AND (@IsUserAdmin = 1 AND up.EmployeeID = @EmployeeID)
....

如果EmployeeID为1,我只想应用@IsUserAdmin过滤器。

我该怎么做?

3 个答案:

答案 0 :(得分:0)

您可以使用case表达式来执行此操作:

join Permission up 
  on up.PermissionID =c.PermissionID 
  and up.EmployeeId = case 
    when @IsUserAdmin = 1 
      then @EmployeeID
    else up.EmployeeId
    end

case表达式基本上表示如果@IsUserAdmin = 1,则up.EmployeeId必须等于@EmployeeId,否则up.EmployeeId必须等于up.EmployeeId

如果up.EmployeeId可以为空,您可以在up.EmployeeIdisnull(up.EmployeeId,0)中包含coalesce(up.EmployeeId,0)个引用,以使其评估为相等。

答案 1 :(得分:0)

由于这是INNER JOIN,因此不将两个连接表都涉及的过滤器更好地移动到WHERE子句。引擎并不关心,但它只是使查询对程序员更具可读性。

...
JOIN Permission up ON up.PermissionID = c.PermissionID
...
WHERE
(up.EmployeeID = @EmployeeID OR @IsUserAdmin <> 1)
...
OPTION(RECOMPILE);

如果@IsUserAdmin不是1,则@EmployeeID的值无关紧要。

如果@IsUserAdmin为1,则过滤器中将使用@EmployeeID的值。

Erland Sommarskog在Dynamic Search Conditions in T‑SQL中详细讨论了这类查询。他解释了为什么您通常希望为此类查询添加OPTION(RECOMPILE)

答案 2 :(得分:-1)

加入后使用where语句。

或者不是写出权限 试试这个

(从许可中选择* 其中EmployeeID = @ IsUserAdmin)