运算符

时间:2015-08-28 07:42:26

标签: sql sql-server

在sql查询中有这个奇怪的错误。

查询是这样的。

select * from student where dob between '20150820' and '20150828'

但是在数据库中,dob的列是varchar(14)并且是yyyyMMddhhmmss格式,说我行中的数据是(20150827142545)。如果我触发上面的查询,它不应该像我提到的那样检索任何行yyyyMMdd查询中的格式。但是它会使用昨天的日期(即20150827112535)检索该行,并且无法获取今天的日期(即20150828144532)

为什么会这样?

感谢您的帮助

5 个答案:

答案 0 :(得分:1)

您可以尝试这样:

select * from student 
where convert(date,LEFT(dob,8)) between 
      convert(date'20150820')  and convert(date,'20150828'))

另外,在其他人发表评论时,您需要将日期存储为Date而不是varchar,以避免日后出现此类问题。

答案 1 :(得分:1)

如前所述,您需要使用正确的日期类型才能使行为正常。

select *
from student 
where convert(date,LEFT(dob,8)) between '20150820' and '20150828'

旁注:您不必显式转换文本中的两个日期,因为只要您使用明确的日期表示,即ISO标准“YYYYMMDD”或“YYYY-MM-DD”,这将隐式完成。当然,如果你在变量中保存值,那么使用date | datetime数据类型

declare @startdate date
declare @enddate date

select *
from student 
where convert(date,LEFT(dob,8)) between @startdate and @enddate

旁注2:在表dob列上执行函数将阻止该列上的任何索引在执行计划中充分发挥其潜力,并且可能导致执行速度变慢,如果可以,则为其定义正确的数据类型如果您的性能是一个真正的问题,请使用表dob列或使用持久计算列或物化视图。

旁注3:如果您需要维护数据中的时间部分,即出生日期和时间,请使用以下内容确保捕获所有记录;

select *
from student
where
convert(date,LEFT(dob,8)) >= '20150820'
    and convert(date,LEFT(dob,8)) < dateadd(d,1,'20150828')

答案 2 :(得分:0)

您所要做的就是首先将字符串转换为日期。

select * 
from student 
where dob between convert(date, '20150820') and convert(date, '20150828')

答案 3 :(得分:0)

为什么会这样?

比较从左到右执行,字符的顺序由使用的代码页确定。

  

排序顺序

     

排序顺序指定数据值的排序方式,影响   数据比较的结果。完成数据分类   通过整理,它可以使用索引进行优化。

https://msdn.microsoft.com/en-us/library/ms143726.aspx

答案 4 :(得分:-2)

T-SQL之间存在问题。

但是如果你想要一个快速的答案首先转换为日期并使用&gt; =&lt; =甚至是datediff来进行比较 - 如果你想在两者之间轻松使用并且不关心开始和开始时间,也可以自己写一个函数...