为什么这不起作用?
select *
from
(
select membership_number
from members
where membership_number not like '%[^0-9]%'
) mem
where cast(membership_number as int) > 2
请参阅SQL Fiddle Demo。
子查询应该过滤掉非数字的数据,外部查询将其转换为整数,以便我可以查找任何> 2。
好像它首先运行外部查询的where子句。我该如何解决这个问题?
答案 0 :(得分:2)
也许那样:
select *
from
(
select
membership_number
from
members
where
membership_number not like '%[^0-9]%'
) mem
where Try_Convert(int, membership_number) > 2
答案 1 :(得分:1)
我以前遇到过这个问题。我做的是:
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
没有一个优雅的解决方案,但希望这有帮助
答案 2 :(得分:1)
非常有趣,我试图在SQL Server上重现这个,然后找到它。我将您的查询更改为简单只是为了确保查询不会失败,我可以看到执行计划:
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 Optimization引擎以这种方式工作(正如有人所说 - 没有人可以保证where子句的顺序)。修复它的方法之一可能是在
之前使用ISNUMERICselect *
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
答案 3 :(得分:0)
评论解释了执行计划如何(有时)选择评估cast
之前的like
。 case
声明可以帮助评估顺序,但正如亚当斯提到的那样,即使这种方法也不是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
答案 4 :(得分:0)
你可以试试这个,在下面的查询中执行第一个条件,如果失败那么它就不会执行第二个条件
select
membership_number
from
members
where
isnumeric(membership_number) = 1 and
cast(membership_number as int) > 2
要回答为什么您的查询无效,请查看此explanation here