How to compare two DATE values based only on date part in Oracle?

雨燕双飞 提交于 2019-12-05 16:17:11

问题


I am trying to get counts for last 30 days with the following query -

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

//date_occured field is of type DATE.

Basically, in my query I am trying to compare only the date part in the condition date_occured >= (CURRENT_DATE - 30), but it seems to compare the time too.

I tried the TRUNC as follows -

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

But when run the query it never returns.

I also tried -

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

Again it never returns.

How can I compare only the date parts from two DATE values in Oracle?


回答1:


For this condition you only need to TRUNC the right-hand side:

WHERE date_occured >= TRUNC(CURRENT_DATE - 30)

Why? Because if TRUNC(date_occured) is later than TRUNC(CURRENT_DATE - 30), then any moment in time after TRUNC(date_occured) is bound to be later than TRUNC(CURRENT_DATE - 30) too.

It is obviously always true that date_occured >= TRUNC(date_occured) (think about it).

Logic says that if A >= B and B >= C then it follows that A >= C

Now substitute:

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



回答2:


I think you'll want to trunc in the select part too:

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



回答3:


Try using SYSDATE vs CURRENT_DATE. Sysdate uses the server's local time where CURRENT_DATE returns current date/time for the server in the client's connection's local time.




回答4:


I would tend to suspect that Tony is correct and that you really only want to TRUNC the right-hand side of the expression.

If you do want to TRUNC both sides of the expression and you're encountering performance issues, you probably need a function based index

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

That would allow your original query to use the function-based index.




回答5:


Here is the index friendly approach.

you don't need to use functions on columns if you use Oracle's Native MONTHS_BETWEEN function.

It returns difference in number of months. Days are also given as difference but on the precision side that is why I preferred to use BETWEEN clause

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


来源:https://stackoverflow.com/questions/7433363/how-to-compare-two-date-values-based-only-on-date-part-in-oracle

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!