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:0000000至17-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'))