2010-09-01 18 views
6

Necesito comparar dos fechas usando la función de decodificación de Oracle para ver si una es less than or equal a la otra.Comparación de fechas en Oracle utilizando la función de decodificación

me encontré con este artículo - http://www.techonthenet.com/oracle/functions/decode.php

Donde se dice (en la parte inferior) que la función de decodificación continuación volverá fecha2 si fecha1> fecha2:

decode((date1 - date2) - abs(date1 - date2), 0, date2, date1) 

¿Esto no volver fecha2 si fecha1> = fecha2?

¿O es solo si date1> date2?

¿Existe una solución más fácil?

Respuesta

18

Esa función devolverá la fecha 2 si la fecha 2 < = fecha1. Conectando los valores y traduciendo a pseudo-código, obtienes if 0 - 0 = 0 then date2 else date1 donde ambas fechas son las mismas.

La mejor solución, si está utilizando 8i o posterior es utilizar case:

select case when date1 >= date2 then date2 else date1 end from Your_Table; 

Desde case permite a los operadores de desigualdad, es mucho más fácil de leer.

0

volverá la fecha 2 cuando fecha1> = fecha2

1

Usted podría intentar la función months_between. Calculará el número de meses entre dos fechas, como un número decimal.

select months_between(sysdate+30, sysdate) from dual; 
select months_between(sysdate+15, sysdate) from dual; 

En este ejemplo, el primer parámetro de es mayor que el segundo por lo que volverá 1. La segunda línea muestra ~ 0,48 (cuando se ejecuta a las 11:30 de la mañana del 2010-09-01) Para obtener el los valores de fecha reales:

select case when months_between(sysdate+30, sysdate) > 0 then sysdate+30 else sysdate end from dual; 

En general:

case when months_between(dateA, dateB) > 0 then dateA else dateB 

actualización:

Después de algunos experimentos, parece que la granularidad más fina de esta función es Día.

select months_between(to_date('2010-10-16 23:59:59', 'YYYY-MM-DD HH24:MI:SS'), 
         to_date('2010-10-16 00:00:00', 'YYYY-MM-DD HH24:MI:SS')) 
from dual; 

... devolverá 0

pero

select months_between(to_date('2010-10-17 00:00:00', 'YYYY-MM-DD HH24:MI:SS'), 
         to_date('2010-10-16 00:00:00', 'YYYY-MM-DD HH24:MI:SS')) 
from dual; 

volverá ,032258064516129.

Algunos otra diferencia interesante fecha/comparar las técnicas aquí: http://www.orafaq.com/faq/how_does_one_get_the_time_difference_between_two_date_columns

7

@Allan ya le ha dado la mejor solución para mí, pero si insiste en usar la función decode, puede procesar el resultado de la función sign en su lugar.

http://www.techonthenet.com/oracle/functions/sign.php

sign(a) vuelve -1 si a < 0, 0 si a = 0 y 1 si a > 0. Por lo tanto, la siguiente lógica

if date1 >= date2 then 
    return date1; 
else 
    return date2; 
end if; 

podría reescribirse usando decode de la siguiente manera:

select decode(sign(date2-date1), 
       -1 /*this means date 1 > date 2*/, date1 /* return date1*/, 
       0 /*dates are equal */,   date1 /* again, return date1*/, 
       /*in any other case, which is date2 > date1, return date2*/ date2) 
from dual; 
1

Si usted está tratando de comprobar por fecha - es decir, cada vez es menos de 1/1 de 1/2, y cada uno de 1/1 es igual a cada otro tiempo en 1/1, incluso si Oracle DATE es mayor, entonces usted quiere comparar de la siguiente manera:

TRUNC (DATE1) < = TRUNC (DATE2)

No veo esto en las otras respuestas, es tan básico que me hace preguntarme si estoy malinterpretando la pregunta.

+1

ahora veo que usted ha dicho explícitamente que quería DECODE. Usaría CASE para una pregunta como esta en la que está evaluando una condición booleana. De todos modos, no te olvides de cortar los minutos cuando comparas fechas, a menos que quieras la comparación con la máxima precisión. – orbfish

+0

Excelente punto, lo tuve en cuenta ya que trabajo con fechas bastante a menudo, pero es bueno mencionarlo si otros terminan mirando esto. – Freddy

0

Esto es mejor:

decode(sign(trunc(sysdate) - (trunc(sysdate))), 1, 1, -1, -1, 0 , 0) 

1: date 1 > date 2 
0: date 1 = date 2 
-1: date 1 < date 2 
+0

Inglés solamente por favor – durron597