我使用SQL Server 2014,我尝试以下查询在同一个表中的两个日期之间进行选择,数据类型为nvarchar
,我执行了以下查询,它只显示了三行('30/03/2015','30/04/2015','30/04/2015')
,但实际上有('29/02/2015','30/03/2015','31/04/2015','30/04/2015','30/04/2015')
select RegisteredDate
from Student
where Student.RegisteredDate between convert(nvarchar, '30/01/2014', 103)
and convert(nvarchar, '30/04/2015', 103)
答案 0 :(得分:3)
反过来说,你正在比较字符串的另一种方式:
select RegisteredDate from Student
where convert(date, Student.RegisteredDate, 103) between '20140130' and '20150430'
事实上,保存为字符串的那些日期按以下顺序排序:
'29/02/2015',
'30/03/2015',
'30/04/2015',
'30/04/2015',
'31/04/2015'
现在想象一下你在哪里添加过滤器值?
'29/02/2015',
'30/01/2014' --start date
/-------------\
|'30/03/2015',|
|'30/04/2015',|
|'30/04/2015',|
\-------------/
'30/04/2015' --end date
'31/04/2015'
所以between
将返回这三行。
您还有数据29/02/2015
。在2015
二月28
结束(表格中的数据不正确)。如果你正确选择类型,你将永远无法插入这些值。所以结论是:
为您的数据使用适当的数据类型!
答案 1 :(得分:2)
正如我已阅读其他答案和评论,我建议您首先将“RegisteredDate”的数据类型从“nvarchar”更改为“date”。其次使用这个标准'yyyy-MM-dd'代码就是你需要的
select RegisteredDate
from Student
where Student.RegisteredDate between '2014-01-30' and '2015-04-30'
你不需要任何转换,这就是我为自己做的事情
答案 2 :(得分:1)
尝试将字符串转换为日期,而不是将表中的所有日期转换为字符串。
您正在将表中的所有记录转换为字符串,并且可能是数百万条记录。这样不仅会使您的表现更好,更重要的是您会将它们与日期进行比较,而不是将其作为字符串进行比较。
正如我在评论中所说,字符串比较从左边开始逐个字母顺序使用字母顺序。例如: 20/01/1302 将在 01/12/4016 之后作为" 2" char追逐" 1" ASCII中的char。
更新:如果仍然是nvarchar类型,则将Student.RegisteredDate转换为日期。如果可以,我建议你改变类型。如果您不这样做,它可能是错误和性能问题的根源。
SQL Server 2014使字符串自动转换为日期,但仅在需要时才进行。比较' 30/04/2015'带有nvarchar的字符串只是一个String比较。