2010-03-03 24 views
46

Estoy usando la base de datos Oracle. Quiero ejecutar una consulta para verificar los datos entre dos fechas.Oracle date "Between" Query

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' 

Pero no obtengo ningún resultado de la consulta anterior. Creo que tengo que usar "me gusta" y "%". Pero no sé dónde usarlos. Por favor, arroja algunas luces sobre esto.

gracias de antemano.

Respuesta

74

A juzgar por su salida parece que usted tiene definió START_DATE como una marca de tiempo. Si fuera una fecha regular, Oracle podría manejar la conversión implícita. Pero como no es necesario, debes convertir explícitamente esas cadenas para que sean fechas.

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> 

Pero solo recibimos una fila. Esto es porque START_DATE tiene un elemento de tiempo. Si no especificamos el componente de tiempo, Oracle lo predetermina a la medianoche. Eso está muy bien para el lado de del BETWEEN pero no para el lado hasta:

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> 

edición

Si no se puede pasar en el componente de tiempo hay un par de opciones. Una de ellas es cambiar la cláusula WHERE para eliminar el elemento de tiempo de los criterios:

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

Esto podría tener un impacto en el rendimiento, ya que descalifica a cualquier índice b-árbol en el START_DATE. En su lugar, necesitaría construir un índice basado en funciones.

Alternativamente se podría añadir el elemento de tiempo a la fecha en el código:

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

Debido a estos problemas muchas personas prefieren evitar el uso de between mediante la comprobación de límites fecha como esta:

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

No puedo pasar la fecha de solo tiempo. –

+0

wow funciona bien APC ... muchas gracias por su apoyo –

+0

@APC funcionaba como encanto en ORACLE 11 G – Alex

20

es necesario convertir los a las fechas reales en lugar de cadenas, intente esto:

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

Editado tratar con formato que especifica:

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

Gracias por su respuesta rápida. Pero obtengo el origen y la fecha del archivo de acción en este formato "17-JAN-10". Así itried así: SELECT * FROM \t uson_assetaccess DONDE fechaacceso ENTRE TO_DATE ('17 -FEB-10' , 'DD-MMM-aa') y TO_DATE ('17 -FEB-10' , 'DD-MMM- yy '); Pero me sale un error: ORA-01821: formato de fecha no reconocido –

+0

Solo tiene que usar diferentes especificadores de formato, reemplace el "MMM" por "MON", vea mi edición. –

+0

Gracias de nuevo por la respuesta inmediata. Pero he utilizado esa consulta, pero ahora el error de formato de fecha se ha ido. ahora no tengo datos encontrados error incluso los datos están ahí en la tabla. Creo que en la fecha de la tabla está el tiempo, pero estamos enviando solo con fecha. ¿Es por esa razón? Por favor, aclare –

3

Como correctamente señaló APC, su columna start_date parece ser TIMESTAMP pero también podría ser TIMESTAMP CON LOCAL TIMEZONE o TIMESTAMP WITH TIMEZONE datatype. Esto bien podría influir en cualquier consulta que estuvieras haciendo sobre los datos si tu servidor de base de datos estuviera en una zona horaria diferente a ti. Sin embargo, vamos a mantener esto simple y supongamos que está en la misma zona horaria que su servidor. Primero, para darle confianza, verifique que start_date sea un tipo de datos TIMESTAMP.

Utilice el comando SQLPlus DESCRIBE (o el equivalente en su IDE) para verificar que esta columna sea un tipo de datos TIMESTAMP.

por ejemplo

DESCRIBE mitabla

deben informar:

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

Si se informa como un Tipo = TIMESTAMP a continuación, puede consultar sus rangos de fechas con la simple conversión de la fecha TO_TIMESTAMP, uno que requiere sin argumento (o imagen).

Utilizamos TO_TIMESTAMP para garantizar que cualquier índice en la columna START_DATE sea considerado por el optimizador. La respuesta de APC también señaló que se podría haber creado un índice basado en función en esta columna y que influiría en el predicado SQL, pero no podemos comentar sobre eso en esta consulta. Si desea saber cómo averiguar qué índices se han aplicado a la tabla, publique otra pregunta y podemos responder por separado.

Así, suponiendo que hay un índice en fecha_inicial, que es un tipo de datos TIMESTAMP y desea que el optimizador para tenerla en cuenta su SQL sería:

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

+.999999999 está muy cerca, pero ISN' t bastante 1 por lo que la conversión de 17-JAN-10 será tan cerca de la medianoche en ese día como sea posible, por lo tanto, la consulta devuelve ambas filas.

La base de datos ver el ENTRE como de 15-ENE-10 00: 00: 00: 0.000.000 a 17-ENE-10 23: 59: 59: 99 999 y por lo tanto incluirá todas las fechas de 15a, 16 y 17 de enero de 2010 sea cual sea el componente de tiempo de la marca de tiempo.

Espero que ayude.

Dazzer

1

Fecha Entre Consulta

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'); 
1

siguiente consulta también se puede utilizar:

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')) 
+2

Si una tabla es grande y la columna de fecha está indexada, debe evitar las expresiones, use 'start_date between to_date (' 15/01/2010 ',' mm/dd/aaaa ') y a_fecha ('01/17/2010', 'mm/dd/aaaa') + 1' en su lugar. – Dmitry