Oracle根据年份返回不一致的结果来选择日期

时间:2013-05-01 08:38:33

标签: sql oracle datetime

我遇到了一个我修改过的Oracle视图的特殊问题。这个想法是我有一个存储所有选举候选人的基础表,并且还有一个选举日期栏,告诉我们这个候选人的选举是什么,如此。

NAME       | ELECTION_DATE
---------------------------
John Smith | 01-APR-2011
Alan Cooper| 02-MAY-2013

ELECTION_DATE列存储为日期。我们使用2011年的以下声明为2011年和2013年构建了2个观点。

where election_date >= to_date(2011,'yyyy') and election_date < to_date(2012,'yyyy')

我们认为只会记录上面的John Smith记录,但事实并非如此。奇怪的是,当我们为2013年的观点做到这一点时。

where election_date >= to_date(2013,'YYYY') and election_date < to_date(2014,'YYYY')

它只获得了Alan Cooper的记录。更奇特的是,如果我们为2011年的观点做到这一点。

where election_date >= to_date(2010,'yyyy') and election_date < to_date(2011,'yyyy')

我们只获得了John Smith的记录,而不是Alan Cooper的记录,这是我们想要的,但不是我们的预期。

我们随后将它们更改为两种语句之间的行为完全相同,即在2010年至2011年期间获得约翰史密斯记录,2011年至2012年之间没有任何结果,2013年至2014年期间获得了Alan Cooper记录。

在我写这篇文章的同时,我的同事设法通过使用这个更明确的陈述来修复它。

where election_date between  '01-JAN-2011' AND '01-JAN-2012'

但我仍然想知道为什么上述陈述仍然如此奇怪?关于使用to_date函数几年我可能会缺少什么?

2 个答案:

答案 0 :(得分:4)

您是否看过to_date()函数实际生成的内容?

select to_date(2011, 'yyyy'), to_date(2012, 'yyyy'), to_date(2013, 'yyyy')
from dual;

TO_DATE(2011,'Y TO_DATE(2012,'Y TO_DATE(2013,'Y
--------------- --------------- ---------------
01-MAY-11       01-MAY-12       01-MAY-13

根据这些日期,您获得的结果是正确的。

如果您未指定月份和日期,则默认为当月的第一天,但​​时间默认为午夜。从documentation for date time literals开始,这是我可以找到的唯一官方参考:

  

如果指定没有时间组件的日期值,则为默认值   时间是午夜(00:00:00或12:00:00,24小时和12小时制   时间,分别)。如果您指定没有日期的日期值,那么   默认日期是当月的第一天。

如果您打算使用

where election_date between  '01-JAN-2011' AND '01-JAN-2012'

...然后您仍然应该使用to_date(),因为您依赖于将来可能会更改的默认日期格式掩码,并且取决于会话。 between也具有包容性,因此使用您的2011年观点将包括2012年1月1日举行的选举,这可能不是您想要的,因此使用>=<是也许安全。或者使用日期文字:

where election_date >= date '2011-01-01' and election_date < date '2012-01-01'

答案 1 :(得分:1)

尝试将年份提取为VARCHAR2并进行比较

select * from table where to_char(ELECTION_DATE, 'yyyy') = `2011` 
or to_char(ELECTION_DATE, 'yyyy') = '2012'