sql - 有时可以对不匹配 WHERE 子句的行计算 SELECT 表达式吗?

标签 sql sql-server sql-server-2008

我想知道 SELECT 中的表达式是否可行要评估与 WHERE 不匹配的行的语句列表条款?

来自执行顺序documented here ,似乎SELECTWHERE之后很长时间进行评估,但是我在现实生活中的查询中遇到了一个非常奇怪的问题类似于下面的查询

为了让您了解上下文,在示例中,SomeOtherTable有一个a_varchar始终包含 code 数值的列105,但可能包含其他代码的非数字值。

查询语句有效:

    SELECT an_id, an_integer FROM SomeTable

    UNION ALL

    SELECT an_id, CAST(a_varchar AS int)
    FROM SomeOtherTable
    WHERE code = 105

以下查询提示无法转换 a_varcharint :

SELECT 1
FROM (
    SELECT an_id, an_integer FROM SomeTable

    UNION ALL

    SELECT an_id, CAST(a_varchar AS int)
    FROM SomeOtherTable
    WHERE code = 105
) i
INNER JOIN AnotherOne a
    ON a.an_id = i.an_id

最后,以下查询有效:

SELECT 1
FROM (
    SELECT an_id, an_integer FROM SomeTable

    UNION ALL

    SELECT 
        an_id, 
        CASE code WHEN 105 THEN CAST(a_varchar AS int) ELSE NULL END
    FROM SomeOtherTable
    WHERE code = 105
) i
INNER JOIN AnotherOne a
    ON a.an_id = i.an_id

因此,我能找到的唯一解释是 JOIN ,查询以不同的方式得到优化 CAST(a_varchar AS int)即使 code <> 105 也会被执行.

查询针对 SQL SERVER 2008 运行。

最佳答案

当然。

您引用的文档中有一个名为SELECT 语句的逻辑处理顺序的部分。这不是物理处理顺序。它解释了查询本身是如何解释的。例如,select 子句中定义的别名不能在 where 子句中引用,因为 where 子句逻辑上 首先处理。

事实上,SQL Server有能力在读取数据时通过进行各种数据转换操作来优化查询。这是一个很好的性能优势,因为数据位于本地内存中,并且操作可以简单地就地完成。但是,以下操作可能会失败并出现运行时错误:

select cast(a_varchar as int)
from table t
where a_varchar not like '%[^0-9]%';

在实际处理流程中尝试转换之后应用过滤器。我碰巧认为这是一个错误;想必,微软的人并不这么认为,因为他们没有费心去解决这个问题。

有两种解决方法可用。第一个是 try_convert(),它执行转换并在失败时返回 NULL,而不是运行时错误。第二个是 case 语句:

select (case when a_varchar not like '%[^0-9]%' then cast(a_varchar as int) end)
from table t
where a_varchar not like '%[^0-9]%';

关于sql - 有时可以对不匹配 WHERE 子句的行计算 SELECT 表达式吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26180070/

相关文章:

从 Datetime2 中提取时间的 SQL 函数

sql-server-2008 - Web2Py 不会连接到 MSSQL

sql-server - MsSQL xml 解析为十进制

SQLite查询: How to find out the Average of last X records for every person

sql - 如何编写条件 "x = y",使其在 x 和 y 均为 NULL 时为真?

c# - 我们在 MS-Access 中有交易吗?

sql-server - 乏味的 SQL Server TVP : parameter. value.getTime 不是 datetime 的函数

sql-server-2008 - 如何为插入/选择中的每一行增加变量

使用动态 SQL 的 SQL Server XML 输出

mysql - SQL CASE SUM 给我 0