Tengo un campo de fecha varchar2 'Created_Date' con el formato 'MM / DD / YYYY HH24: MI' en una tabla de Oracle Ahora, quiero todos los campos donde el rango de fechas está entre 1-ENE-2014 y 31-MAR-2014 .

He utilizado la siguiente consulta y sé que algunas de mis fechas del 31 de marzo de 2014 se están perdiendo.

Select * 
from Table1
where to_date(Created_Date, 'MM/DD/YYYY HH24:MI') between '1-JAN-2014' and '31-MAR-2014'

Por favor sugiera lo mismo. Gracias.

0
0nir 4 feb. 2015 a las 22:49

4 respuestas

La mejor respuesta

Lo que creo que está sucediendo es que sus VARCHAR2 "fechas" tienen componentes de tiempo, en cuyo caso podrían caer después del 31 de marzo de 2014. Le sugiero que haga lo siguiente:

SELECT * FROM table1
 WHERE TO_DATE(created_date, 'MM/DD/YYYY HH24:MI') >= '01-JAN-2014'
   AND TO_DATE(created_date, 'MM/DD/YYYY HH24:MI') < '01-APR-2014'
2
David Faber 4 feb. 2015 a las 19:58

En primer lugar, nunca almacene fechas en un campo de texto (es decir, varchar2), eso es solo buscar problemas.

En cualquier caso, no se recuperará el 31 de marzo de 2014, ya que todas las fechas tienen un componente de tiempo.

Sus datos reales tienen algo de tiempo, supongamos que son las 10 a. M. Del 31 de marzo. Luego, le pide que recupere todos los elementos MENOS que el 31 de marzo de 2014 ... sin componente de tiempo, por lo tanto, asume "00:00:00" o medianoche.

Dado que las 10 de la mañana son 10 horas después de la medianoche ... no es más temprano.

Probablemente quieras:

  Select * 
  from Table1
  where to_date(Created_Date, 'MM/DD/YYYY HH24:MI') 
        between to_date('01-JAN-2014','dd-mon-yyyy')
             and to_date('31-MAR-2014','dd-mon-yyyy')+1;

Convierta siempre las fechas usted mismo, nunca confíe en la conversión implícita. Luego, simplemente haga "+1" para pasar al día siguiente y obtendrá todos los registros "Antes del 1 de abril", que es lo que desea ... en cualquier momento, el 31 de marzo.

1
Ditto 4 feb. 2015 a las 20:00

Está obteniendo los registros hasta 31-MAR-2014 00:00 inclusive, pero también desea incluir todas las horas de ese último día.

Obtenga los registros hasta (pero sin incluir) 00:00 al día siguiente:

where to_date(Created_Date, 'MM/DD/YYYY HH24:MI') >= '1-JAN-2014' and
  to_date(Created_Date, 'MM/DD/YYYY HH24:MI') < '1-APR-2014'
1
Guffa 4 feb. 2015 a las 20:00

Por supuesto, las fechas del 31 de marzo no se muestran, si tienen un componente de tiempo. Al usar between, solo llegará hasta la medianoche cuando comienza el 31 de marzo. Así es como funcionan las fechas y cómo funcionan las entregas.

Aquí hay dos soluciones. Primero, use solo la fecha:

where to_date(Created_Date, 'MM/DD/YYYY') between date '2014-01-01' and date '2014-03-31'

O dígalo un poco diferente:

where to_date(Created_Date, 'MM/DD/YYYY HH24:MI') >= date '2014-01-01' and
      to_date(Created_Date, 'MM/DD/YYYY HH24:MI') < date '2014-04-01'

Observe que también cambié de usar la constante de cadena al operador date. Esta palabra clave le permite proporcionar una constante de fecha en formato AAAA-MM-DD estándar ISO.

Mi preferencia es una combinación de estos dos métodos:

where to_date(Created_Date, 'MM/DD/YYYY') >= date '2014-01-01' and
      to_date(Created_Date, 'MM/DD/YYYY') < date '2014-04-01'

En general, trato de evitar usar between con fechas, precisamente por este tipo de problemas.

2
Gordon Linoff 4 feb. 2015 a las 19:59