Sql - WHERE 条件的显式顺序?
Posted
技术标签:
【中文标题】Sql - WHERE 条件的显式顺序?【英文标题】:Sql - Explicit order of WHERE conditions? 【发布时间】:2016-03-07 16:12:58 【问题描述】:有没有办法明确说明 WHERE 条件发生的顺序?我意识到查询优化器将查看 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
这可能会失败,因为可以在确定 table_name 字段是否为数字之前评估 CAST(因此会抛出无效转换错误)。
肯定有办法做到这一点吗?
【问题讨论】:
【参考方案1】:使用派生表:
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,存在 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 实现也可能如此。
【讨论】:
不漂亮,但我会接受。谢谢!【参考方案2】:我认为您是在问评估是否会短路 - 阅读此内容可能会有所帮助:
Is the SQL WHERE clause short-circuit evaluated?
因此,您可能需要在尝试第二个条件之前评估第一个条件。在 MSSQL 中,您可以使用 CTE 来执行第一个操作。或者,另一种选择可能是使用 CASE 仅在某些条件下执行第二个。
【讨论】:
以上是关于Sql - WHERE 条件的显式顺序?的主要内容,如果未能解决你的问题,请参考以下文章