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的问题中,没有聚合函数,所以这应该不是问题。和往常一样,通过测试来验证。