SQL'Or'运算符。它在以下场景中如何工作?

时间:2009-01-23 18:25:09

标签: sql sql-server null three-valued-logic

我一直在努力优化查询,并遇到了让我质疑我是如何一直使用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为'Test'的所有记录以及Col2为'Data'的任何记录

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

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

突然间,我得到0行返回。

我是否误解过OR只评估表达式,直到它找到一个真实的结果,或者是否有一个条件会导致2个不同的结果返回不同的结果?

4 个答案:

答案 0 :(得分:8)

“OR只评估表达式,直到找到TRUE结果”

它只需要,但这不是你的问题(实际上这就是你在原始案例中拯救你的东西)。你的两个问题实际上并不等同。

我认为你在Column2中有NULL,这永远不会导致(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

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

答案 1 :(得分:3)

OR并非包罗万象,特别是因为它在括号中。你所拥有的更大的是:WHERE X AND Y。事实上X和Y本身就是使用OR的布尔表达式并不重要:它们是单独计算的,然后将结果提供给AND运算符。

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

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

答案 2 :(得分:1)

仅供参考,您可以通过非常简单的实验来确定并非所有条件都必须进行评估。

我在Oracle中做过这个,但我希望你在SQL Server中会得到类似的结果。

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

D
-
X

OR之后的条件一定不能被评估,因为它会引起被零除错误。

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

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

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

答案 3 :(得分:0)

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

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