2013-05-01 58 views
2

我遇到了我修改的Oracle视图的一个特殊问题。这个想法是我有一个存储所有选举候选人的基础表,并且还有一个选举日期栏,告诉我们这个候选人是什么选举的一部分,就像这样。Oracle根据返回不一致结果的年份选择日期

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

ELECTION_DATE列存储为日期。我们构建了2次,2011年和2013年,使用以下statment 2011年

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

其中我们认为会捡起刚刚约翰·史密斯的记录之上,但事实并非如此。特别的是,当我们为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') 

我们得到的只是约翰史密斯的记录,而不是Alan Cooper的记录,这是我们想要的,但不是我们所期望的。

然后,我们改变了他们之间的陈述和他们的表现完全一样,即2010年至2011年获得约翰史密斯唱片,2011年至2012年之间一无所获,2013年至2014年获得了Alan Cooper唱片。

虽然我正在写这篇文章,但我的同事设法通过使用这个更明确的声明来解决它。

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

但我仍然想知道为什么上述说法仍然如此奇怪?我错过了几年使用to_date函数可能吗?

回答

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年1月1日举行的选举可能包含2012年1月1日举行的选举,这可能不是您想要的选举,所以使用>=<也许是安全的。或者使用日期文字:

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

此行 - 如果您没有指定月份和日期,那么它们默认为当月的第一天 - 解释问题!我假设(错误地)只有一年的to_date函数默认为01/01而不是01/{current_month}。谢谢! – 2013-05-01 09:32:35

1

尝试提取一年的VARCHAR2和做的比较

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

这将工作,但渲染任何指数都没用 - 这样做反过来更有意义恕我直言。 – 2013-05-01 09:21:19

+1

除非这是一张非常常见的操作表,这保证了一个基于函数的索引。 – 2013-05-01 09:37:35