-->

Oracle中的日期范围内检索数据(Retrieve data within a date rang

2019-11-04 00:36发布

我有一个表tbldeptdivision如下:

ID  DEPTID  DIVISIONID  FROMDATE    TODATE      REMARKS 
--- ------- ----------- ----------- ----------- --------
21  21      5           31-AUG-99   01-JAN-80   NULL

我有查询

select *
  from tbldeptdivision
 where deptid = 21
   and trunc(sysdate) between to_date(fromdate,'dd-Mon-yyyy')
                          and to_date(todate,'dd-mon-yyyy');

它返回我没有价值。 任何人都可以说为什么? '31-AUG-99'实际上是'31-AUG-1999''01-JAN-80'实际上是'01-JAN-2080' 。 会有什么确切的查询?

Answer 1:

当你的todate是一个date的问题,从列的值从一个日期为varchar和回日期无用转换梗:

to_date()转换一个VARCHAR到一个DATE值。 如果您传递给该函数的值已经是一个DATE Oracle将首先通过隐含应用默认NLS格式的日期转换为varchar,而将然后再转换为varchar回的日期,再次应用默认NLS格式。

在第一个(隐含的)转换,你正在失去世纪的这一年,因此这是错误的,然后当VARCHAR转换回一个date

所以你的情况下是由于调用来完成to_date(fromdate,'dd-Mon-yyyy')

  • todate包含(实际)日期值:一九八○年一月三十○日
  • 隐式转换为varchar使得该'01-JAN-80'
  • 从VARCHAR到日期的转换,然后假定80年应该是2080(同样基于隐式数据类型转换的规则)。

一般的规律是:

不要在使用TO_DATE() DATE (或TIMESTAMP )列

如果您需要摆脱在时间部分的DATE列使用trunc()代替:

where trunc(sysdate) between trunc(fromdate) and trunc(todate)


Answer 2:

假设FROMDATE/TODATE数据类型是varchar2那么当你做to_date ;

select to_date('01-JAN-80','dd-mon-yyyy') from dual;
OutPut: January, 01 0080 00:00:00

所以它不会是'01-JAN-2080' ,但'01-JAN-0080'

即使FROMDATE/TODATE数据类型是date tusing to_date是不是一个好主意;

create table t(c date);
insert into t select sysdate from dual;
select c, to_date(c,'dd-mon-yyyy') from t;

输出:

C                           TO_DATE(C,'DD-MON-YYYY')
August, 25 2015 10:55:36    August, 25 0015 00:00:00

不过这一年是0015不是2015

如果你的数据类型的列日是再使用trunc to get the日期部分don't use to_date`。

select * 
from tbldeptdivision
where deptid=21
and trunc(sysdate) between trunc(fromdate) 
and trunc(todate)


Answer 3:

在你的领域中使用函数where子句减慢生产。 这是同样的逻辑和运行速度将更快。

where fromdate <= trunc(sysdate)
and todate > trunc(sysdate )


文章来源: Retrieve data within a date range in Oracle