只是一个相当普遍的日期过滤问题......
我有一个包含YYYYMMDD(没时间)的日期字段。 当我在当月查找交易时,如果我这样做,我会得到不同的结果......
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) - 我应该先转换为日期吗?
答案 0 :(得分: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'
有关详细信息,请参阅Aaron Bertrand的Bad habits to kick : mis-handling date / range queries。
好吧,在您说列类型为nvarchar(8)
后,很明显字符串'2017-03-01'和'20170301'的比较无法导致什么都好。
使用BETWEEN
时,您需要比较字符串,而不是日期。当您使用YEAR
和MONTH
时,服务器会将您的nvarchar(8)
值转换为场景后面的日期(以及废品效果)。
你可以将日期存储为nvarchar(8)
,但是你需要将它们与相同格式的字符串进行比较,如下所示(没有破折号):
and MyDateField >= '20170301'
and MyDateField <= '20170331'
最好将它们存储为char(8)
,但将它们存储为date
会更好。 date
为3个字节,nvarchar(8)
为至少17个字节。