SQL“或”运算符。在以下场景中它是如何工作的?

Posted

技术标签:

【中文标题】SQL“或”运算符。在以下场景中它是如何工作的?【英文标题】:SQL 'Or' operator. How does it work in the following scenario? 【发布时间】:2009-01-23 18:25:09 【问题描述】:

我一直致力于优化查询,遇到的情况让我质疑我一直以来如何使用 SQL 的 OR 运算符。 (SQL Server 2000 也是)

我有一个查询,其中条件 (WHERE) 子句如下所示:

WHERE (Column1 = @Param1 or Column1 LIKE @Param1 + '%')
AND (@Param2 = '' OR Column2 = @Param2 OR Column2 LIKE @Param2 + '%')

现在,我一直都明白 SQL 中的 OR 对这两个表达式都求值。因此,所有对左侧表达式评估为 true 的记录将与所有在右侧表达式评估为 true 的记录一起返回。例如:

SELECT * FROM TABLE1
WHERE COL1 = 'Test' OR Col2 = 'Data'

这将返回 COL1 为“测试”的所有记录以及 Col2 为“数据”的任何记录

在上面的示例中,我将 Column2 条件修改为:

AND(Column2 LIKE ISNULL(@Param2, '') + '%')

突然间,我返回了 0 行。

我是否误认为 OR 只计算表达式,直到找到 TRUE 结果,或者是否存在会导致 2 个不同返回不同结果的条件?

【问题讨论】:

您可以在更改后的完整位置发布吗? 【参考方案1】:

“OR 只计算表达式,直到找到 TRUE 结果”

它只需要,但这不是你的问题(实际上这是在你原来的情况下拯救你的原因)。您的两个查询实际上并不等效。

我认为您在 Column2 中有 NULLs,这永远不会导致 (Column2 LIKE ISNULL(@Param2, '') + '%') 为真 - 在您的原始版本中,@Param2 = '' 掩盖了这种情况,因为它是真的(有时)

也许:

(ISNULL(Column2, '') LIKE ISNULL(@Param2, '') + '%')

记住 NULL 的三值逻辑:

TRUE and UNKNOWN: UNKNOWN
TRUE or UNKNOWN: TRUE

FALSE and UNKNOWN: FALSE
FALSE or UNKNOWN: UNKNOWN

但我不确定您的优化是否真的有帮助。

【讨论】:

【参考方案2】:

OR 并非包罗万象,尤其是在括号中时。从那以后你所拥有的是:WHERE X AND Y。 X 和 Y 本身是使用 OR 的布尔表达式这一事实并不重要:它们分别进行评估,然后将结果提供给 AND 运算符。

[编辑]: 再次阅读,我可能误解了你的问题。考虑到这一点,我将不得不采用另一个答案,因为NULL LIKE '%' 返回 NULL,在这种情况下与 false 相同。你可以试试这个:

COALESCE(Column2,'') LIKE COALESCE(@param2,'') + '%'

【讨论】:

【参考方案3】:

仅供参考,您可以做一些非常简单的实验来查看并非所有条件都必须进行评估。

我在 Oracle 中执行了此操作,但我希望您在 SQL Server 中会得到类似的结果。

dev> select * from dual where 1=1 or 1/0 = 3;

D
-
X

OR 之后的条件必须没有被评估,因为它会引发被零除的错误。

布尔运算符的这种处理通常被称为“短路”,AFAIK 在现代语言中是相当标准的。它也可以应用于 AND 表达式——如果第一个条件为假,则评估第二个条件没有意义,因为整个表达式不可能为 TRUE。

更多信息:http://en.wikipedia.org/wiki/Short-circuit_evaluation

无论如何,正如 Cade 所说,您真正的问题可能是对 NULL 的错误处理。

【讨论】:

Oracle 不同。 MS-SQL 会做左手然后短路。 Oracle 会根据优化器决定先做哪一边,所以每次运行命令时它都可以切换。 SQL Server 不会短路 Where 子句中的任何 AND 或 OR:weblogs.sqlteam.com/mladenp/archive/2008/02/25/… 在 MS-SQL 2005 中,语句 select 'short circuit works' 其中 1=0 和 1/0 = 0 表示短路。该链接可能与 2008 年有关,因此可能需要调查。 该链接适用于所有 sql server 版本。【参考方案4】:

MS-SQL 将首先评估左侧,除非需要,否则不会继续。

这与AND连接器相同,将评估左侧,如果为false则不评估右侧。

【讨论】:

以上是关于SQL“或”运算符。在以下场景中它是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章

SQL入门:SQL运算符有哪些?它们是如何工作的?

如何包装尚未包装的单词或单词序列?

sql子查询!基本 sql 查询中 ANY 运算符的问题。不知道为啥在我的查询中需要它以及它将如何工作?

智能化运维场景分析

智能化运维六大场景

在 Ruby 中,“=>”是啥意思,它是如何工作的? [复制]