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 中有 NULL
s,这永远不会导致 (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“或”运算符。在以下场景中它是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章