web-dev-qa-db-ja.com

デコード機能を使用したOracleの日付の比較

Oracleデコード関数を使用して2つの日付を比較し、一方がless than or equalであるかどうかを確認する必要があります。

この記事を見つけました- http://www.techonthenet.com/Oracle/functions/decode.php

Date1> date2の場合、以下のデコード関数がdate2を返すことを(下部に)示しています。

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

Date1> = date2の場合、これはdate2を返しませんか?

それとも、date1> date2の場合だけですか?

より簡単な解決策はありますか?

7
Freddy

Date2 <= date1の場合、この関数はdate2を返します。値をプラグインして擬似コードに変換すると、両方の日付が同じであるif 0 - 0 = 0 then date2 else date1が得られます。


8i以降を使用している場合のより良い解決策は、caseを使用することです。

SELECT CASE WHEN date1 >= date2 THEN date2 ELSE date1 END FROM Your_Table;

caseは不等式演算子を許可するため、はるかに読みやすくなります。


または、より簡潔にしたい場合は、n個の値の小さい方を返すように設計された関数を使用できます。

SELECT LEAST(date1, date2) FROM Your_Table;

(逆のGREATEST関数もあります。)

19
Allan

@Allanはすでに私に最善の解決策を提供していますが、decode関数の使用を主張する場合は、代わりにsign関数の結果を処理できます。

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

sign(a)-1 if a < 00 if a = 01 if 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;
7
Kirill Leontev

months_between 関数。 2つの日付の間の月数を10進数として計算します。

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

この例では、最初のパラメーターが2番目のパラメーターよりも大きいため、1が返されます。2行目は〜0.48を返します(2010-09-01の午前11時30分頃に実行された場合)。実際の日付値を取得するには、次のようにします。

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

更新:

いくつかの実験の後、この関数の最も細かい粒度はDayであるように思われます。

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

日付で確認しようとしている場合、つまり、Oracle DATEが大きい場合でも、1/1のすべての時間は1/2未満であり、1/1のすべての時間は1/1の他のすべての時間と同じです。 -次に、次のように比較します。

TRUNC(DATE1)<= TRUNC(DATE2)

これは他の回答には見られません。非常に基本的なため、質問を誤解しているのではないかと思います。

1
orbfish

これの方が良い:

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
1
Ciurdy

date1> = date2の場合、date2を返します

0