Oracle to_date具有四分之一格式的函数

时间:2010-08-04 18:32:09

标签: sql oracle oracle10g sql-date-functions

我需要找到一些季度创建的记录。例如,我正在寻找在2008年第四季度和2010年第一季度之间创建的所有记录。我在WHERE子句中有这个:

...and r.record_create_date between to_date('2008 4','YYYY Q')
                                and to_date('2010 1','YYYY Q')

但甲骨文说:ORA-01820: format code cannot appear in date input formatQ是一个有效的日期格式符号,所以我不确定发生了什么。这甚至是在日历季度之间找到值的有效方法,还是有更好的方法?


如果我执行此操作,也很有趣,也可能是相关的:

select to_date('2009','YYYY') from dual;

我的IDE中显示的值为2009-08-01。我原以为2009-08-04,因为今天2010-08-04

此:

select to_date('2009 1','YYYY Q') from dual;

当然,失败了。

(Oracle 10g)

5 个答案:

答案 0 :(得分:4)

Oracle说:ORA-01820: format code cannot appear in date input formatQ是一个有效的日期格式符号,所以我不确定发生了什么。

http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/sql_elements004.htm#i34948表2.15的第二栏。转换为日期,时间戳等时,并非所有格式元素都被允许

我建议不要在日期范围检查之间使用。人们通常会在期望包含的结束日期间错过价值观。所以我会翻译:

and r.record_create_date between to_date('2008 4','YYYY Q')
                             and to_date('2010 1','YYYY Q')

and to_date('2008-10-01', 'YYYY-MM-DD') <= r.record_create_date 
and record_create_date < to_date('2010-04-01', 'YYYY-MM-DD') -- < beginning of 2Q2010.

答案 1 :(得分:1)

有人在OTN上问了同样的问题:http://forums.oracle.com/forums/thread.jspa?threadID=1081398&tstart=255

问题的关键在于你可以在<=> 中指定TO_DATE函数中的“Q”。

鉴于您已经指定了日期的一部分,为什么不提供整个日期?还要注意,to_date('2010 1','YYYY Q')会给你2010年1月1日,当你真正想要2010年3月31日......在第二个到午夜。

答案 2 :(得分:1)

由于四分之一到几个月之间的关系是一对多,所以做TO_DATE('2008 1','yyyy q')是没有意义的;应该退回哪个日期?本季度的第一季度,季度结束,......? (另一方面,将日期转换为季度 - 如TO_CHAR(SYSDATE,'yyyy q')是有道理的,因为特定日期仅存在于四分之一。)

因此,如果您确实需要查询日期介于两个季度之间的查询,则必须“自行滚动”(明确说明季度开始/结束的日期。)

作为旁注,如果有人考虑不使用TO_DATE,请不要使用以下内容:WHERE date_value BETWEEN'date string1'和'date string2'没有TO_DATE函数。它采用默认日期格式,在某些情况下可以完全避免潜在有用的索引。

下面是一个示例,其中相同的查询可能会有不同的结果。

select sysdate from dual where sysdate between '1-Jan-10' and '31-Dec-10';


SYSDATE
---------
04-AUG-10

SQL> alter session set nls_date_format = 'YYYY-MM-DD';

Session altered.

SQL> select * from dual where sysdate between '1-Jan-10' and '31-Dec-10'; 

no rows selected

(请注意,在第二个实例中,不会返回任何错误。它只是假设1月10日,0001和12月10日,0031。)

答案 3 :(得分:0)

我认为最好的方法是输入季度开始日期和季度结束日期,甚至不用打扰to_date。我想如果你使用

between '1-Jan-10' and '31-Dec-10'
例如,那么你没有(我相信在Oracle中)需要to_date并且输入季度数字并不困难

答案 4 :(得分:0)

在Oracle中计算一季度的第一天和一年中季度的最后一天: 我用事实

start_month = -2 + 3 *季度

last_month = 3 *季度

variable v_year    number

variable v_quarter number

exec :v_year     :=2017

exec :v_quarter:=4

select :v_year    as year,
       :v_quarter as quarter,
       to_date(:v_year||to_char(-2+3*:v_quarter,'fm00'),'yyyymm')        as quarter_start,
       last_day(to_date(:v_year||to_char(3*:v_quarter,'fm00')||'01 23:59:59','yyyymmdd hh24:mi:ss')) as quarter_end
from dual a;


YEAR|QUARTER|QUARTER_START      |QUARTER_END        
2017|      4|2017-10-01 00:00:00|2017-12-31 23:59:59