如何在 WHERE 子句中使用条件不同的列?

Posted

技术标签:

【中文标题】如何在 WHERE 子句中使用条件不同的列?【英文标题】:How to use conditional different columns in WHERE clause? 【发布时间】:2016-11-07 13:05:58 【问题描述】:

我想在 SQL Server 2014 查询的 WHERE 子句中使用完全不同的条件,而不仅仅是更改参数。

我有以下子句

WHERE        (dbo.SecurityCheckUserInADGroups.CWID = @cwid2) AND (dbo.SecurityCheckUserInDatabaseRoles.Server = @server)

如果变量 @cwid2 为 NULL 或为空,我想用

替换 AND 语句的整个第一部分
dbo.SecurityCheckLDAPGroupName.DatabaseUserName = @role2

所以这里不仅参数而且列也发生了变化。

我用类似的方法尝试过 If、Case 和 Iif,但不被接受:

(IIF (LEN(@cwid1) > '0, 'dbo.SecurityCheckUserInADGroups.CWID = @cwid2','dbo.SecurityCheckLDAPGroupName.DatabaseUserName = @role2'))

它一直告诉我“在预期条件的上下文中指定的非布尔类型的表达式”

有什么办法可以解决这个问题吗?

【问题讨论】:

使用 AND/OR 代替。 【参考方案1】:

使用基本逻辑即可:

WHERE ((@cwid <> '' AND dbo.SecurityCheckUserInADGroups.CWID = @cwid2) OR
       (COALESCE(@cwid, '') = '' AND dbo.SecurityCheckLDAPGroupName.DatabaseUserName = @role2)
      ) AND
      (dbo.SecurityCheckUserInDatabaseRoles.Server = @server)

【讨论】:

【参考方案2】:

最通用的解决方案是

Where (@var is null and col1=val1)
   Or (@var is not null and col2=val2)

因为查询优化器有时会在 OR 上阻塞,所以当性能可能成为问题(大型数据集等)时,我倾向于寻找其他解决方案,但上述方法可能值得首先尝试。

如果你确实需要更具体的东西,iif 逻辑的诀窍是它返回一个值进行比较,而不是一个要评估的谓词。你可以做类似的事情

Where col1 = iif(@var is null, val1, col1)
  And col2 = iif(var is null, col2, val2)

这里的想法是,您的“不关心”情况(例如 var 为 null 时 col2 的值)解析为“始终为真”。但在某些情况下(例如 col1 或 col2 可能为 NULL),此特定解决方案会失败。​​

这就是为什么第一种方法最通用的原因

【讨论】:

【参考方案3】:
WHERE CASE WHEN ISNULL(@cwid2,'') <> '' THEN 
      dbo.SecurityCheckUserInADGroups.CWID = @cwid2 ELSE 
      dbo.SecurityCheckLDAPGroupName.DatabaseUserName = @role2 
      END 
AND dbo.SecurityCheckUserInDatabaseRoles.Server = @server

【讨论】:

以上是关于如何在 WHERE 子句中使用条件不同的列?的主要内容,如果未能解决你的问题,请参考以下文章

mysql'WHERE'条件中的列号

如何获得 2 个不同 WHERE 子句的列的平均值?

不同的 SELECTs 子句更改行数(具有相同的 WHERE 条件)

如何将 if 条件放在 where 子句中

使用子查询添加具有不同 where 子句的列

SQL在where子句中使用子选择中的列