Oracledate“之间”查询

我正在使用oracle数据库。 我想执行一个查询来检查两个date之间的数据。

NAME START_DATE ------------- ------------- Small Widget 15-JAN-10 04.25.32.000000 PM Product 1 17-JAN-10 04.31.32.000000 PM select * from <TABLENAME> where start_date BETWEEN '15-JAN-10' AND '17-JAN-10' 

但是我没有从上面的查询中得到任何结果。 我想我必须使用“喜欢”和“%”。 但我不知道在哪里使用它们。 请把这个灯点亮一下。

提前致谢。

从你的输出来看,你已经将START_DATE定义为一个时间戳了。 如果这是一个正常的date,Oracle将能够处理隐式转换。 但是,因为它不是你需要明确地把这些string作为date。

 SQL> alter session set nls_date_format = 'dd-mon-yyyy hh24:mi:ss' 2 / Session altered. SQL> SQL> select * from t23 2 where start_date between '15-JAN-10' and '17-JAN-10' 3 / no rows selected SQL> select * from t23 2 where start_date between to_date('15-JAN-10') and to_date('17-JAN-10') 3 / WIDGET START_DATE ------------------------------ ---------------------- Small Widget 15-JAN-10 04.25.32.000 SQL> 

但是我们仍然只有一行。 这是因为START_DATE有一个时间元素。 如果我们不指定时间组件,Oracle默认它是午夜。 这对于BETWEEN并不合适,但对于直到这一方面来说,

 SQL> select * from t23 2 where start_date between to_date('15-JAN-10') 3 and to_date('17-JAN-10 23:59:59') 4 / WIDGET START_DATE ------------------------------ ---------------------- Small Widget 15-JAN-10 04.25.32.000 Product 1 17-JAN-10 04.31.32.000 SQL> 

编辑

如果你不能通过时间组件,有几个select。 一个是更改WHERE子句从标准中删除时间元素:

 where trunc(start_date) between to_date('15-JAN-10') and to_date('17-JAN-10') 

这可能会对性能产生影响,因为它在START_DATE不符合任何b-tree索引。 你需要build立一个基于函数的索引。

或者,您可以将时间元素添加到代码中的date:

 where start_date between to_date('15-JAN-10') and to_date('17-JAN-10') + (86399/86400) 

由于这些问题,许多人更喜欢通过检查date边界来避免使用这种情况:

 where start_date >= to_date('15-JAN-10') and start_date < to_date('18-JAN-10') 

您需要将这些转换为实际date而不是string,请尝试以下操作:

 SELECT * FROM <TABLENAME> WHERE start_date BETWEEN TO_DATE('2010-01-15','YYYY-MM-DD') AND TO_DATE('2010-01-17', 'YYYY-MM-DD'); 

编辑来处理指定的格式:

 SELECT * FROM <TABLENAME> WHERE start_date BETWEEN TO_DATE('15-JAN-10','DD-MON-YY') AND TO_DATE('17-JAN-10','DD-MON-YY'); 

正如APC正确指出的那样,start_date列看起来像是一个TIMESTAMP,但也可能是一个TIMESTAMP WITH LOCAL TIMEZONE或TIMESTAMP WITH TIMEZONE数据types。 如果您的数据库服务器与您自己处于不同的时区,这些可能会影响您对数据执行的任何查询。 但是,让我们保持这个简单,并假设你在与你的服务器在同一时区。 首先,为了给您信心,请检查start_date是否为TIMESTAMP数据types。

使用SQLPlus DESCRIBE命令(或IDE中的等效项)来validation此列是否为TIMESTAMP数据types。

例如

描述mytable

应该报告:

 Name Null? Type ----------- ----- ------------ NAME VARHAR2(20) START_DATE TIMESTAMP 

如果它被报告为Type = TIMESTAMP,那么你可以用最简单的TO_TIMESTAMPdate转换来查询你的date范围,一个不需要参数(或图片)的date范围。

我们使用TO_TIMESTAMP来确保优化器考虑START_DATE列中的任何索引。 APC的答案还指出,基于函数的索引可能已经创build在这个列上,这会影响SQL谓词,但我们不能评论这个查询。 如果你想知道如何找出哪些索引已经应用到表格中,请发表另一个问题,我们可以单独回答。

所以,假设在start_date上有一个索引,这是一个TIMESTAMP数据types,你希望优化器考虑它,你的SQL将是:

 select * from mytable where start_date between to_timestamp('15-JAN-10') AND to_timestamp('17-JAN-10')+.9999999 

+.999999999非常接近,但不是一个,所以17-JAN-10的转换将尽可能接近午夜,因此你查询返回两行。

数据库将在15-JAN-10 00:00:00:000000017-JAN-10 23:59:59:99999之间看到BETWEEN,因此包括2010年1月15日,16日和17日的所有date时间戳的组件。

希望有所帮助。

Dazzer

查询之间的date

 SELECT * FROM emp WHERE HIREDATE between to_date (to_char(sysdate, 'yyyy') ||'/09/01', 'yyyy/mm/dd') AND to_date (to_char(sysdate, 'yyyy') + 1|| '/08/31', 'yyyy/mm/dd'); 

以下查询也可以使用:

 select * from t23 where trunc(start_date) between trunc(to_date('01/15/2010','mm/dd/yyyy')) and trunc(to_date('01/17/2010','mm/dd/yyyy')) 
Interesting Posts