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

Sql 外部查询在内部查询之前运行,sql,sql-server,tsql,Sql,Sql Server,Tsql,为什么这不起作用 select * from ( select membership_number from members where membership_number not like '%[^0-9]%' ) mem where cast(membership_number as int) > 2 看 子查询应该过滤掉非数字的数据,外部查询将其转换为整数,以便我可以查找任何大于2的数据 它似乎首先运行外部查询的where子句。我该怎么解决这个问题呢?也许:

为什么这不起作用

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

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

它似乎首先运行外部查询的where子句。我该怎么解决这个问题呢?

也许:

select *
from
(
    select
        membership_number
    from
        members
    where
        membership_number not like '%[^0-9]%'
) mem
where Try_Convert(int, membership_number) > 2

我以前有过这个问题。我所做的是:

1,您可以拥有一个视图,该视图具有以下功能:

select membership_number
    from members
    where membership_number not like '%[^0-9]%'
2,或使用临时表

3或用例条款:

select *
from
(
    select membership_number
    from members
    where membership_number not like '%[^0-9]%'
) mem
where (CASE WHEN ISNUMERIC(membership_number) THEN cast(membership_number as int) ELSE 0 END) > 2

没有一个优雅的解决方案,但希望这有助于

注释解释了执行计划如何(有时)选择在执行类似的
之前评估
演员阵容。一个
案例
陈述可以帮助确定评估顺序,但正如亚当斯提到的,即使这种方法也不是100%

select  *
from    members
where   case
            when membership_number like '%[^0-9]%' then 0
            when cast(membership_number as int) > 2 then 1
            else 0
        end = 1

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

select *
from
(
    select membership_number
    from members
    where membership_number not like '%[^0-9]%'
) mem
where membership_number > '2'
执行计划具有带谓词的表扫描:

[master].[dbo].[members].[membership_number]>'2' 
    AND NOT [master].[dbo].[members].[membership_number] like '%[^0-9]%'
这是因为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

您可以尝试这样做,在下面的查询中,执行第一个条件,如果失败,则不会执行第二个条件

select
    membership_number
  from
    members
where 
isnumeric(membership_number) = 1 and 
cast(membership_number as int) > 2

要回答为什么您的查询不起作用,请检查此

您是否自行运行内部查询以确保它返回您期望的结果?这很酷。我以前从未听说过SQL Fiddle。如果您使用稍微修改的
WHERE
查看执行计划,它会将子查询WHERE子句与主
WHERE
:我仍在考虑如何防止这种行为。请检查此项-T-SQL函数并不意味着您的问题有特定的执行顺序,您可以使用WHERE ISNUMERIC(成员身份号码)=1和cast(成员身份号码为int)>2@EthanLi是的,但问题是没有指定版本。
CASE
语句并不总是短路:@AdamWenger在帖子中指出+1@AdamWenger:在本文中,它提到了聚合函数的一个特定情况,这些聚合函数被指定为始终首先求值。在OP的问题中,没有聚合函数,所以这应该不是问题。和往常一样,通过测试来验证。