2017-03-01 131 views
2

只是一个相当普遍的日期过滤问题...SQL日期过滤

我有一个包含年月日(没时间)日期字段。 当当月寻找交易,我得到不同的结果,如果我做...

and MyDateField between '2017-03-01' and '2017-03-31' 

到,如果我做...

and Year(MyDateField) = '2017' and Month(MyDateField) = '3' 

它看起来像“之间”的方法是排除3月1日发生的任何事情(其他交易未来的日期)。

这是为什么?

这些是从方法“之间”的结果...

20170303 
20170327 
20170309 
20170324 
20170331 
20170306 

而这些是“年/月”结果...

20170303 
20170327 
20170309 
20170324 
20170301 
20170331 
20170306 
20170301 

的数据被存储为nvarchar(8) - 我应该首先转换日期吗?

+1

发布您的样品数据和预期结果。 – Mansoor

+0

你可以发表一些样本,说明你的日期数据类型是什么样子的,它的数据类型 – TheGameiswar

+0

被编辑以显示结果 – dazzathedrummer

回答

4

BETWEEN是包含性的。

and MyDateField between '2017-03-01' and '2017-03-31' 

是一样的:

and MyDateField >= '2017-03-01' 
and MyDateField <= '2017-03-31' 

我唯一的解释是,MyDateField类型是date,但datetime或类似的东西,可能时间组件。

而您的表中的一些值实际上有这个非零时间组件。

所以,你的查询应该是这样的:

and MyDateField >= '20170301' 
and MyDateField < '20170401' 

详情亚伦伯特兰看到Bad habits to kick : mis-handling date/range queries


好了,以后你说这列类型为nvarchar(8),则可以很明显看出字符串比较“2017年3月1日”和“20170301”不能带来什么好东西。

当您使用BETWEEN时,您会比较字符串,而不是日期。当您使用YEARMONTH时,服务器会将您的nvarchar(8)值转换为场景后的日期(并废除性能)。


可能店日期为nvarchar(8),但你需要将它们在相同的格式比较字符串,像这样(没有破折号):

and MyDateField >= '20170301' 
and MyDateField <= '20170331' 

这将是更好的将它们存储为char(8),但将它们存储为date会更好。对于date,3字节,对于nvarchar(8),至少17字节。

请参阅Bad habits to kick : choosing the wrong data type

+1

是的 - nvarchar是问题! – dazzathedrummer