2

我需要找到一些在多个季度创建的记录。例如,我正在查找 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 format。这Q是一个有效的日期格式符号,所以我不确定发生了什么。这甚至是在日历季度之间查找值的有效方法,还是有更好的方法?


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

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;

当然,失败。

(甲骨文 10g)

4

5 回答 5

4

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

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

我建议不要使用 between 进行日期范围检查。人们通常会在预期包含的结束日内错过价值。所以我会翻译:

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.
于 2010-08-04T18:54:10.737 回答
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 日……午夜时分。

于 2010-08-04T18:45:23.040 回答
1

由于季度和月份之间的关系是一对多的,所以这样做没有意义 TO_DATE('2008 1', 'yyyy q'); 应该返回什么日期?第一季度,季度末,...?(另一方面,将日期转换为季度 - 例如 TO_CHAR(SYSDATE, 'yyyy q') 是有意义的,因为特定日期仅存在于一个季度中。)

因此,如果您确实想要一个查找介于两个季度之间的日期的查询,您将不得不“自己滚动”(明确说明一个季度的开始/结束日期。)

附带说明一下,如果有人考虑不使用 TO_DATE,请不要使用以下内容:WHERE date_value BETWEEN 'date string1' and 'date string2' without the TO_DATE function。它采用默认日期格式,在某些情况下可以完全避免潜在有用的索引。

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

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

(请注意,在第二种情况下没有返回错误。它只是假设 0001 年 1 月 10 日和 0031 年 12 月 10 日。)

于 2010-08-04T21:08:58.347 回答
0

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

between '1-Jan-10' and '31-Dec-10'

例如,那么你不需要(我相信在 Oracle 中)需要 to_date 并且它并不比输入季度数字难多少

于 2010-08-04T18:49:12.660 回答
0

在 Oracle 中计算季度的第一天和季度的最后一天:I Use the fact

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
于 2018-02-01T20:10:32.080 回答