Как сравнить два значения DATE, основанные только на дате в Oracle?

Я пытаюсь получить счет за последние 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);

Снова он никогда не возвращается.

Как сравнить только части даты с двумя значениями DATE в Oracle?

Ответ 1

Для этого условия вам нужно только TRUNC в правой части:

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)

Ответ 2

Я думаю, вы тоже захотите обрезать в выделенной части:

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

Ответ 3

Попробуйте использовать SYSDATE vs CURRENT_DATE. Sysdate использует локальное время сервера, где CURRENT_DATE возвращает текущую дату/время для сервера в локальное время подключения клиента.

Ответ 4

Я хотел бы заподозрить, что Тони прав, и что вы действительно хотите TRUNC правую часть выражения.

Если вы хотите TRUNC обе стороны выражения, и вы сталкиваетесь с проблемами производительности, вам, вероятно, нужен индекс на основе функции

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

Это позволит вашему исходному запросу использовать функциональный индекс.

Ответ 5

Вот индекс дружественный подход.

вам не нужно использовать функции для столбцов, если вы используете функцию Oracle Native MONTHS_BETWEEN.

Возвращает разницу в количестве месяцев. Дни также указываются как разница, но с точки зрения точности, поэтому я предпочел использовать предложение BETWEEN

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