外部查询在内部查询之前运行

Loc*_*ock 9 sql t-sql sql-server

为什么这不起作用?

select *
from
(
    select membership_number
    from members
    where membership_number not like '%[^0-9]%'
) mem
where cast(membership_number as int) > 2
Run Code Online (Sandbox Code Playgroud)

请参阅SQL Fiddle演示.

子查询应该过滤掉非数字的数据,外部查询将其转换为整数,以便我可以查找> 2的任何内容.

好像它首先运行外部查询的where子句.我该如何解决这个问题?

out*_*man 1

非常有趣,我尝试在 SQL Server 上重现这个并发现了下一个。我将您的查询更改为简单只是为了确保查询不会失败并且我可以看到执行计划:

select *
from
(
    select membership_number
    from members
    where membership_number not like '%[^0-9]%'
) mem
where membership_number > '2'
Run Code Online (Sandbox Code Playgroud)

执行计划具有带谓词的表扫描:

[master].[dbo].[members].[membership_number]>'2' 
    AND NOT [master].[dbo].[members].[membership_number] like '%[^0-9]%'
Run Code Online (Sandbox Code Playgroud)

所以这是因为 SQL 优化引擎以这种方式工作(正如有人所说 - 没有人可以保证你的 where 子句的顺序)。修复它的方法之一可能是在之前使用 ISNUMERIC

select *
from
(
    select membership_number
    from members
    where membership_number not like '%[^0-9]%'
) mem
where ISNUMERIC(mem.membership_number) = 1 and cast(mem.membership_number as int) > 2
Run Code Online (Sandbox Code Playgroud)