2016-03-07 82 views
5

有没有什么方法可以明确说明WHERE条件发生的顺序?我认识到,查询优化器将着眼于在WHERE子句中的所有部分,以确定最有效的方式来满足查询,因为在这些答案中指出:Sql - WHERE条件的显式顺序?

Does order of where clauses matter in SQL

SQL - Does the order of WHERE conditions matter?

然而,有无法检查其他条件依赖的条件吗?答案之一来自这些线程倒是我后,但不提供一个解决方案:

select * 
from INFORMATION_SCHEMA.TABLES 
where ISNUMERIC(table_name) = 1 and CAST(table_name as int) <> 0 

这可能会失败,因为CAST能够确定table_name的字段是否是数字之前评估(因此抛出无效投射错误)。

当然,必须有办法实现这个目标吗?

回答

4

使用派生表这样:

SELECT* 
FROM(
    select * 
    from INFORMATION_SCHEMA.TABLES 
    where ISNUMERIC(table_name) = 1 
) AS i 
WHERE CAST(table_name as int) <> 0 

另外,为了最有可能的运行,你可以使用一个CASE语句:

select * 
from INFORMATION_SCHEMA.TABLES 
where 0<>(CASE WHEN ISNUMERIC(table_name) = 1 
      THEN CAST(table_name as int) 
      ELSE 0 END) 

应当指出的是, SQL Server(我已经用过的唯一RDBMS)存在CASE技巧会失败的情况。请参阅documentation on CASE, Remarks

CASE语句按顺序评估其条件,并停止满足条件满足的第一个条件。 在某些情况下,在CASE语句接收表达式的结果作为其输入之前,将对表达式求值。评估这些表达式的错误是可能的。首先评估出现在CASE语句的WHEN参数中的聚合表达式,然后将其提供给CASE语句。例如,当生成MAX聚合的值时,以下查询产生除零错误。这发生在评估CASE表达式之前。

WITH Data (value) AS 
( 
SELECT 0 
UNION ALL 
SELECT 1 
) 
SELECT 
    CASE 
     WHEN MIN(value) <= 0 THEN 0 
     WHEN MAX(1/value) >= 100 THEN 1 
    END 
FROM Data ; 

我怀疑这也可能是其他RDBMS实现真实的。

+1

不漂亮,但我会接受。谢谢! – McFixit

1

我认为,如果评估可以短路你问 - 它可能有助于阅读:

Is the SQL WHERE clause short-circuit evaluated?

所以,你可能需要在尝试前一秒来评价的首要条件。在MSSQL中,你可以使用CTE来完成第一个。或者,另一个选择可能是使用CASE在特定条件下仅执行第二个。