SQL连接是否只执行最少数量的条件?

时间:2012-02-28 10:03:03

标签: sql sql-server tsql boolean

如果我运行以下内容,请使用C#。

if(obj.a() && obj.b()){
    // do something
}

函数b仅在a返回true时执行。同样的事情发生在下面吗?

select
    *
from
    tablea a
    inner join tableb b
        isnumeric(b.col1) = 1
        and cast(b.col1 as int) = a.id

cast仅在b.col1是数字时执行吗?

3 个答案:

答案 0 :(得分:2)

您可以使用CASE表达式模拟短路评估。

ON CASE WHEN ISNUMERIC(b.col1) = 1
       THEN CAST(b.col1 AS int)
       ELSE NULL
   END = a.id

答案 1 :(得分:2)

这涵盖了SQL-Server中的短期评估:

http://www.sqlservercentral.com/articles/T-SQL/71950/

简而言之:评估顺序取决于查询优化器。

编辑:正如Martin评论的那样,这并不能保证订单,因为它也可以进行优化。从上面的链接(我应该完全阅读):

  

针对SQL Server 2000运行时,不会引发任何错误,而是SQL Server   2005年和2008年实施优化以推动非SARGable   谓词从子查询进入索引扫描导致   声明失败。

     

要避免此问题,可以使用CASE重写查询   表达,也许有点模糊,但保证不会失败。

所以这应该保证首先评估ISNUMERIC

SELECT aData.*,bData.*
FROM #TableA aData INNER JOIN  #TableB bData
ON aData.id = CASE ISNUMERIC(bData.col1) WHEN 1 THEN CAST(bData.col1 AS INT) END

忽略我的第一种方法(可能每次都不起作用):

您应该修改您的联接以确保正确评估

SELECT aData.*,bData.*
FROM #TableA aData INNER JOIN 
(
    SELECT col1
    FROM #TableB b
    WHERE ISNUMERIC(b.col1) = 1
 ) AS bData
 ON aData.id = CAST(bData.Col1 AS int)

示例数据:

create table #TableA(id int)
create table #TableB(col1 varchar(10))

insert into #TableA values(1);
insert into #TableA values(2);
insert into #TableA values(3);
insert into #TableA values(4);

insert into #TableB values('1');
insert into #TableB values('2');
insert into #TableB values(null);
insert into #TableB values('4abc');

SELECT aData.*,bData.*
FROM #TableA aData INNER JOIN 
(
    SELECT col1
    FROM #TableB b
    WHERE ISNUMERIC(b.col1) = 1
 ) AS bData
 ON aData.id = CAST(bData.Col1 AS int)

drop table #TableA;
drop table #TableB;

结果:

id  col1
1    1
2    2

答案 2 :(得分:1)

来自HERE

没有。如果优先级不是由格式或括号确定的,则表达式的有效评估通常从左到右执行。但是,依赖于实现是否实际上是从左到右计算表达式,特别是当操作数或运算符可能导致条件被引发时,或者如果可以在不完全评估表达式的所有部分的情况下确定表达式的结果。