Couple things. One, using BETWEEN
is not that great for dates because dates aren't exactly discrete. It is better to use something like:
WHERE the_date >= TRUNC(start_dt)
AND the_date < TRUNC(end_dt) + 1;
Two, it looks like you're storing the date as the number of seconds that has passed since 1/1/1970? You might be better off at least using ANSI date literals and intervals:
SELECT DATE'1970-01-01' + NUMTODSINTERVAL(ifs_start_date_time_key, 'SECOND')
You can use an alias for the above, but you can't refer to it in the WHERE
clause unless you use a subquery. So putting all of this together:
SELECT start_date_time_key FROM (
SELECT DATE'1970-01-01' + NUMTODSINTERVAL(irf.start_date_time_key, 'SECOND') AS start_date_time_key
FROM mytable irf
) WHERE start_date_time_key >= DATE'2015-02-20'
AND start_date_time_key < DATE'2015-02-20' + INTERVAL '1' DAY; -- or just DATE'2015-02-20' + 1;
Someone asked in the comments why not use BETWEEN
with dates. Well, in this case it almost certainly wouldn't matter because there isn't going to be an index on start_date_time_key
when it's converted to a DATE
, but it will matter in cases where there is an index on the DATE
column, so avoiding BETWEEN
for dates is just a good habit to get into. I just tried the following on a medium-sized table in my DB:
SELECT * FROM mytable
WHERE TRUNC(date_created) BETWEEN TRUNC(SYSDATE-2) AND TRUNC(SYSDATE-1);
The above gave me a full table scan with a high CPU cost. Then I did this:
SELECT * FROM mytable
WHERE date_created >= TRUNC(SYSDATE-2)
AND date_created < TRUNC(SYSDATE);
That gave me a range scan on the index (because there is an index on date_created
) and a fair CPU cost. I can imagine the contrast would be even greater for a "big" table with millions of rows.
Alternately, one could put a function-based index on the DATE
column (e.g., TRUNC(mydate)
), but that won't help you if your date values also have time portions. Just eschew BETWEEN
-- using >=
and <
isn't that much more typing.
Another thought just struck me. If the column IRF.START_DATE_TIME_KEY
is itself indexed, then it might be better to convert the dates to similar integers and use those.
SELECT DATE'1970-01-01' + NUMTODSINTERVAL(irf.start_date_time_key, 'SECOND') AS start_date_time_key
FROM mytable irf
WHERE irf.start_date_time_key >= (DATE'2015-02-20' - DATE'1970-01-01') * 86400
AND irf.start_date_time_key < (DATE'2015-02-20' + 1 - DATE'1970-01-01') * 86400
It's not pretty, but it would have the advantage of using the index on IRF.START_DATE_TIME_KEY
in the event there is one.
WHERE
clauses. – David Faber