在论坛中出现的比较难的sql问题:46(日期条件出现的奇怪问题)
2016-01-14 10:30
465 查看
最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了。
所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路。
关于日期条件出现的奇怪问题。
http://bbs.csdn.net/topics/390498925
select top 1 ekeyid,ProbeMaterial,Result,LabTestDate from PatientLabTestResults
where ProbeMaterial='Ca'
and LabTestDate between convert(datetime,2013/1/1) and
convert(datetime,'2013/6/24') order by LabTestDate desc
这样查的出结果,变成
select top 1 ekeyid,ProbeMaterial,Result,LabTestDate from PatientLabTestResults
where ProbeMaterial='Ca'
and LabTestDate between convert(datetime,2013/1/1) and
convert(datetime,2013/6/24) order by LabTestDate desc
这样后就查不出结果了,其实只是去除了2013/6/24的'号而已,这个大家能理解是什么问题吗?
其实就是,
2013/5/1 就是一个除法运算,结果为402。
2013/6/24 做除法运算后,就是13。
由于datetime数据类型的默认值为:'1900-01-01 00:00:00',
所以上面的convert(datetime,2013/5/1)就是'1900-01-01 00:00:00' 再加上402,
就是'1901-02-07 00:00:00.000',
而convert(datetime,2013/6/24)就是是'1900-01-01 00:00:00' 再加上 13,
就是'1900-01-14 00:00:00.000',
所以就会查不出结果来。
所以,上面的2013/5/1 要写成 '2013/5/1',一定要加上引号。
所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路。
关于日期条件出现的奇怪问题。
http://bbs.csdn.net/topics/390498925
select top 1 ekeyid,ProbeMaterial,Result,LabTestDate from PatientLabTestResults
where ProbeMaterial='Ca'
and LabTestDate between convert(datetime,2013/1/1) and
convert(datetime,'2013/6/24') order by LabTestDate desc
这样查的出结果,变成
select top 1 ekeyid,ProbeMaterial,Result,LabTestDate from PatientLabTestResults
where ProbeMaterial='Ca'
and LabTestDate between convert(datetime,2013/1/1) and
convert(datetime,2013/6/24) order by LabTestDate desc
这样后就查不出结果了,其实只是去除了2013/6/24的'号而已,这个大家能理解是什么问题吗?
if OBJECT_ID('t') is not null drop table t go create table t(d datetime) insert into t select cast('2013-05-01' as datetime) as d union all select cast('2013-05-10' as datetime) /* 1. 通过查询计划能看出,SQL Server把下面的查询转化成了: select * from t where d >= convert(datetime,2013/5/1,0) and d <= convert(datetime,'2013/6/24',0) 也就是查询条件: d >= convert(datetime,2013/5/1,0) and d <= convert(datetime,'2013/6/24',0) 进一步转化: d >= '1901-02-07 00:00:00.000' and d <= 2013-06-24 00:00:00.000 这样就能查询出结果集。 */ select * from t where d between convert(datetime,2013/5/1) and convert(datetime,'2013/6/24') /* 2. 通过查询计划能看出,SQL Server把下面的查询转化成了: select * from t where d >= convert(datetime,2013/5/1,0) and d <= convert(datetime,2013/6/24,0) 也就是查询条件: d >= convert(datetime,2013/5/1,0) and d <= convert(datetime,2013/6/24,0) 进一步转化: d >= '1901-02-07 00:00:00.000' and d <= '1900-01-14 00:00:00.000' 由于SQL Server 把2013/6/24中的斜杠,当成了除号,也就是按除法计算了, 比如:2013/6/24 就等于13,那么由于datetime默认值是默认值: 1900-01-01 00:00:00, 那么加上13后,就是1900-01-14 00:00:00.000,这样后就查不出结果了. */ select * from t where d between convert(datetime,2013/5/1) and convert(datetime,2013/6/24)
其实就是,
2013/5/1 就是一个除法运算,结果为402。
2013/6/24 做除法运算后,就是13。
由于datetime数据类型的默认值为:'1900-01-01 00:00:00',
所以上面的convert(datetime,2013/5/1)就是'1900-01-01 00:00:00' 再加上402,
就是'1901-02-07 00:00:00.000',
而convert(datetime,2013/6/24)就是是'1900-01-01 00:00:00' 再加上 13,
就是'1900-01-14 00:00:00.000',
所以就会查不出结果来。
所以,上面的2013/5/1 要写成 '2013/5/1',一定要加上引号。
相关文章推荐
- Redis的安装和使用之三------redis.conf配置释义
- 在论坛中出现的比较难的sql问题:45(用户在线登陆时间的小时、分钟计算问题)
- SQL集合函数中case when then 使用技巧
- MySQL之终端terminal管理数据库、数据表、数据的基本操作
- mysql中selec sum返回null的解决方法
- MySQL创建用户与授权方法
- mysql的学习笔记
- 在论坛中出现的比较难的sql问题:44(触发器专题 明细表插入数据时调用主表对应的数据)
- 数据库连接池的原理
- PostgreSQL的LIMIT子句解析
- mysql字符编码的设置ini
- Redis+Spring缓存实例(windows环境,附实例源码及详解)
- Redis+Spring缓存实例(windows环境,附实例源码及详解)
- Redis+Spring缓存实例(windows环境,附实例源码及详解)
- Redis+Spring缓存实例(windows环境,附实例源码及详解)
- Oracle树查询(查询所有子节点,父节点等等)
- 数据库-表连接
- mysql多行多列合并为一行一列 【转】
- AP:PaymentTerms 的设置&Invoice batch 知识点。
- MySQL5.7多实例自动化部署脚本