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)
GRO
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.
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.
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;
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
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: