web-dev-qa-db-ja.com

Oracleで日付部分のみに基づいて2つのDATE値を比較する方法は?

次のクエリで過去30日間のカウントを取得しようとしています-

_SELECT date_occured, COUNT(*) FROM problem
WHERE date_occured >= (CURRENT_DATE - 30)
GROUP BY date_occured;

//date_occured field is of type DATE.
_

基本的に、私のクエリでは、条件date_occured >= (CURRENT_DATE - 30)の日付部分のみを比較しようとしていますが、時間も比較しているようです。

私は次のようにTRUNCを試しました-

_TRUNC(date_occured) >= TRUNC(CURRENT_DATE - 30)
_

ただし、クエリを実行しても返ることはありません。

私も試しました-

_SELECT date_occured, COUNT(*) FROM problem    
GROUP BY date_occured
HAVING TRUNC(date_occured) >= TRUNC(CURRENT_DATE - 30);
_

再びそれは決して戻りません。

Oracleで2つのDATE値の日付部分のみを比較するにはどうすればよいですか?

12
Bhesh Gurung

この条件では、右側のみを切り捨てる必要があります。

WHERE date_occured >= TRUNC(CURRENT_DATE - 30)

どうして? TRUNC(date_occured)がTRUNC(CURRENT_DATE-30)より遅い場合、TRUNC(date_occured)より後の任意の瞬間もTRUNC(CURRENT_DATE-30)より遅くなるようにバインドされるためです。

Date_occured> = TRUNC(date_occured)(それについて考えてみてください)であることは常に常に真です。

ロジックは、A> = BおよびB> = Cの場合、A> = C

代わりに:

  • A:date_occured
  • B:TRUNC(date_occured)
  • C:TRUNC(CURRENT_DATE-30)
15
Tony Andrews

私もあなたが選択部分で切り詰めたいと思うでしょう:

 SELECT TRUNC(date_occured) AS short_date_occured, COUNT(*)
 FROM problem 
 WHERE date_occured >= trunc(SYSDATE- 30) 
 GROUP BY short_date_occured;
3
Lost in Alabama

私はトニーが正しいこと、そしてあなたは本当に式の右側だけをTRUNCしたいのではないかと疑う傾向があります。

式の両側をTRUNCしたくて、パフォーマンスの問題が発生している場合は、おそらく関数ベースのインデックスが必要です

CREATE INDEX idx_problem_trunc_dt_occured
    ON problem( trunc( date_occurred ) );

これにより、元のクエリで関数ベースのインデックスを使用できるようになります。

1
Justin Cave

SYSDATEとCURRENT_DATEを使用してみてください。 Sysdateは、サーバーのローカル時間を使用します。CURRENT_DATEは、クライアントの接続のローカル時間でのサーバーの現在の日付/時刻を返します。

1
northpole

これがインデックスにやさしいアプローチです。

oracleのネイティブMONTHS_BETWEEN関数を使用する場合、列で関数を使用する必要はありません。

月数の差を返します。日数も差として示されていますが、精度の面から、BETWEEN句を使用することを選択しました。

WHERE MONTHS_BETWEEN(date_occured, CURRENT_DATE - 30) BETWEEN 0 AND 1