2010-09-01 3 views
6

Мне нужно сравнить две даты, используя функцию декодирования Oracle, чтобы увидеть, является ли один из less than or equal другим.Сравнение дат в Oracle с использованием функции декодирования

Я нашел эту статью - http://www.techonthenet.com/oracle/functions/decode.php

Что говорится (в нижней части), что ниже функция декодирования будет возвращать date2 если date1> date2:

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

бы это не вернуть date2 если date1> = дата2?

Или это просто, если date1> date2?

Есть ли более легкое решение?

ответ

18

Эта функция будет возвращать date2 если date2 < = date1. Подключив значения и переведя на псевдокод, вы получите if 0 - 0 = 0 then date2 else date1, где обе даты одинаковы.

Лучшее решение, если вы используете 8i или поздно использовать case:

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

Поскольку case позволяет операторам неравенство, гораздо более удобным для чтения.

0

вернется date2 при date1> = date2

1

Вы можете попробовать функцию months_between. Он рассчитает количество месяцев между двумя датами, как десятичное число.

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

В этом примере первая В параметре больше, чем второй, так он будет возвращать 1. Вторая строка возвращает ~ 0,48 (при выполнении примерно в 11:30 утра на 2010-09-01) Для того, чтобы получить фактические значения даты:

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

В общем:

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

Update:

После некоторых экспериментов, кажется, самая тонкая гранулярность этой функции - День.

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; 

... вернет 0

но

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; 

вернется 0.032258064516129.

Некоторые другие различия интересная дата/сравнить методы здесь: http://www.orafaq.com/faq/how_does_one_get_the_time_difference_between_two_date_columns

7

@ Allan уже дал вам лучшее решение для меня, но если вы настаиваете на использовании функции decode, вы можете обработать результат функции sign.

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

sign(a) возвращает -1 если a < 0, 0 если a = 0 и 1 если a > 0. Таким образом, следующая логика

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

можно переписать, используя decode следующим образом:

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

Если вы пытаетесь проверить на сегодняшний день - то есть, каждый раз, когда в 1/1 меньше чем 1/2, и каждый на 1/1 равен каждому другому времени на 1/1, даже если Oracle DATE больше - тогда вы хотите сравнить следующим образом:

TRUNC (DATE1) < = TRUNC (DATE2)

Я не вижу этого в других ответах, это настолько фундаментально, что мне интересно, не понимаю ли я вопрос.

+1

теперь я вижу, что вы явно сказали, что вы хотели DECODE. Я бы использовал CASE для такого вопроса, когда вы оцениваете логическое условие. Независимо от того, не забудьте отрезать минуты, когда вы сравниваете даты, если вы не хотите, чтобы сравнение было с максимальной точностью. – orbfish

+0

Отличная точка зрения, я объяснил это уже, когда я работаю с датами довольно часто, но неплохо было бы упомянуть, если другие в конечном итоге смотрят на это. – Freddy

0

Это лучше:

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

Только на английском языке – durron597

Смежные вопросы