一个Select 的条件筛选优先问题

$扫地僧$ 2008-03-19 09:06:47
问题如下:
create table T
(
dt varchar(10)
)



insert T select null
insert T select ''
insert T select '2003-07-01'
insert T select '2004-01-05'
insert T select 'SDS'

--这样写是没问题的!!
select dt,Days
from (select dt,datediff(dd,'2003-07-01',dt) as Days from T where ISDate(dt)=1) Temp_A

--但是要是这样写

select dt,Days
from (select dt,datediff(dd,'2003-07-01',dt) as Days from T where ISDate(dt)=1) Temp_A
where Days>=0
就会提示 :
服务器: 消息 241,级别 16,状态 1,行 1
从字符串转换为 datetime 时发生语法错误。

我不明白 为什么会这样!!
按道理我是先把是日期类型的排出了的阿!!

麻烦那位大侠给解释一下 SQL server 里面的 where 语句的筛选原理 !谢谢!!


...全文
539 点赞 收藏 35
写回复
35 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
lyd963 2008-03-20
mark 学习一下
回复
lhsxsh 2008-03-20
先执行的WHERE条件是:datediff(dd,'2003-07-01',dt) > =0
回复
being21 2008-03-20
参与观看!
回帖是一种美德!传说每天回帖即可获得 10 分可用分!
回复
wzjpsq 2008-03-20
学习
回复
shenzilei 2008-03-20
SQL code你可以看SQL的【执行计划】,经过SQL查询器的自动优化后,
在WHERE语句中它是先执行:datediff(dd,'2003-07-01',dt)
再执行:ISDate(dt)=1 这样就会提示【从字符串转换为 datetime 时发生语法错误。】
你应该告诉SQL查询器你要操作的先后顺序。
改成:
select dt,Days from (select dt,datediff(dd,'2003-07-01',dt) as Days from T where ISDate(dt)=1) Temp_A
where (case when ISDate(dt)=1 then Days else
回复
xiaomeixiang 2008-03-19
先执行的WHERE条件是:datediff(dd,'2003-07-01',dt) >=0
回复
xiaomeixiang 2008-03-19
乌龟的方法不笨啊,这样就不会报错,可以查到语句的执行计划:

select dt,Days from (select dt,datediff(dd,'2003-07-01',dt) as Days from T where ISDate(dt)=1) Temp_A where Days> =0
|--Compute Scalar(DEFINE:([Expr1004]=datediff(day,'2003-07-01 00:00:00.000',CONVERT_IMPLICIT(datetime,[ERPDATA].[dbo].[T].[dt],0))))
|--Filter(WHERE:(isdate(CONVERT_IMPLICIT(nvarchar(10),[ERPDATA].[dbo].[T].[dt],0))=(1)))
|--Table Scan(OBJECT:([ERPDATA].[dbo].[T]), WHERE:(datediff(day,'2003-07-01 00:00:00.000',CONVERT_IMPLICIT(datetime,[ERPDATA].[dbo].[T].[dt],0))>=(0)))
回复
xiaoku 2008-03-19
顶300分.
回复
gahade 2008-03-19
楼主讨论的是语句的优化顺序,我学习.

如果是日期型的要用datetime,不要用字符型
回复
dawugui 2008-03-19
[Quote=引用 17 楼 JiangHongTao 的回复:]
引用 5 楼 dawugui 的回复:
错在这个:insert T select 'SDS'
其他没问题.

看来乌龟还是比较笨,LZ是特意增加那条记录用于测试出错的,主要问的是错误原因,而比试错误的地方。
另:比较同意16L的,SQL 的优化机制使得我们的SQL语句缺乏语法保障。
[/Quote]
乌龟不是比较笨,是非常笨.
回复
$扫地僧$ 2008-03-19
[Quote=引用 5 楼 dawugui 的回复:]
错在这个:insert T select 'SDS'
其他没问题.
SQL codecreatetableT (dtvarchar(10))insertTselectnullinsertTselect''insertintoTvalues('2003-07-01')insertintoTvalues('2004-01-05')--insert T select 'SDS'goselectdt,datediff(dd,'2003-07-01',dt)asDaysfromTwhereISDate(dt)=1/*dt Days
---------- -----------
2003-07-01 0
2004-01-05 188*/select*from(selectdt,datediff(dd,'2003-07-01',dt)asDay…
[/Quote]

insert T select 'SDS'
是我故意加上去 !!

我当然知道 这不是时间类型
回复
bote_china 2008-03-19
试了一下,没有楼主所说的错误
回复
yms_wangxm 2008-03-19
凑热闹的
回复
zhuyx808 2008-03-19
分是比较多哈
回复
肥胖的柠檬 2008-03-19
上面的也以说明了
也引用一下我们板主查询优化器对查询条件顺序的影响的示例:
--测试表及数据
CREATE TABLE tb(Col varchar(10))
INSERT tb SELECT '1900-1-1'
UNION ALL SELECT '19aa-1-1'
GO

SELECT * FROM tb
WHERE ISDATE(Col)=1
AND Col<GETDATE()
GO

--建立索引
CREATE INDEX IDX_tb_Col ON tb(Col)
GO

SELECT * FROM tb
WHERE ISDATE(Col)=1
AND Col<GETDATE()
GO

--删除测试
DROP TABLE tb

索引影响查询条件顺序
回复
JiangHongTao 2008-03-19
[Quote=引用 5 楼 dawugui 的回复:]
错在这个:insert T select 'SDS'
其他没问题.
[/Quote]
看来乌龟还是比较笨,LZ是特意增加那条记录用于测试出错的,主要问的是错误原因,而比试错误的地方。
另:比较同意16L的,SQL 的优化机制使得我们的SQL语句缺乏语法保障。
回复
xiaoliaoyun 2008-03-19
SQL 做了优化,它的优化是基于成本,不是基于语法...下面的帖子有讨论
http://topic.csdn.net/u/20071210/10/b7cfec7a-080b-4a30-b62a-92c987d3bcdd.html
回复
wzy_love_sly 2008-03-19
create table T
(
dt varchar(10)
)

insert T select null
insert T select ''
insert T select '2003-07-01'
insert T select '2004-01-05'
insert T select 'SDS'

select dt,Days from (
select dt,
case when isdate(dt)=1 then datediff(dd,'2003-07-01',dt) end as Days from t
) Temp_A where Days> =0


dt Days
2003-07-01 0
2004-01-05 188

直接看执行计划,表扫描先用条件datediff,筛选器才执行 isdate,
感觉有点象函数的优先级别,就算增加不是日期类型的数据,还是不先执行isdate,sql优化问题,不智能
回复
-狙击手- 2008-03-19
查询优化成先执行datediff()了,所以报错
回复
kelph 2008-03-19
select dt,Days  from (select dt,datediff(dd,'2003-07-01',dt) as Days from T ) Temp_A
where (case when ISDate(dt)=1 then Days else -1 end )>=0
回复
加载更多回复
相关推荐
发帖
MS-SQL Server
创建于2007-09-28

3.3w+

社区成员

MS-SQL Server相关内容讨论专区
申请成为版主
帖子事件
创建了帖子
2008-03-19 09:06
社区公告
暂无公告