Reputation: 11572
I'm looking for a way to determine if a timestamp falls between two times, regardless of the date in that timestamp. So for example, if the time in the timestamp falls between '00:00:00.000' (midnight) and '01:00:00.000' (1 A.M.), I'd want to select that row regardless of the particular date.
I've tried lots of different variations on the to_char
and to_date
functions, but I keep getting errors. Coming from Informix, Oracle seems much more complicated.
The thing closest to "correct" (I think) that I've tried is:
SELECT *
FROM my_table
WHERE SUBSTR(TO_CHAR(my_timestamp), 10) > '00:00:00.000'
AND SUBSTR(TO_CHAR(my_timestamp), 10) < '01:00:00.000'
... But nothing works. Any tips or tricks?
I found a way to do it, but I'd still prefer something a little less hacky, if it exists.
SUBSTR(SUBSTR(TO_CHAR(my_timestamp), 11), 0, 12) > '01.00.00.000'
Upvotes: 2
Views: 4403
Reputation: 191275
As a variation on @kubanczyk's answer, since these are timestamps you get an interval when you subtract a value from its truncated form:
select systimestamp - trunc(systimestamp) from dual;
SYSTIMESTAMP-TRUNC(SYSTIMESTAMP)
---------------------------------------------------------------------------
+000000000 09:46:46.589795
Which isn't very helpful. But if you're always looking for exact hours, as in your example, you can extract the hour number from that:
select extract (hour from systimestamp - trunc(systimestamp)) from dual;
EXTRACT(HOURFROMSYSTIMESTAMP-TRUNC(SYSTIMESTAMP))
-------------------------------------------------
9
So in your example you could use:
SELECT *
FROM my_table
WHERE EXTRACT(HOUR FROM my_timestamp - TRUNC(my_timestamp)) = 0
But, this will only be straightforward if the timeslots are exactly aligned with hours; otherwise you'd need to extract other elements too and the logic could get confusing, and @Ankit's approach will be simpler overall.
Upvotes: 0
Reputation: 5072
Your solution looks correct to me except I haven't tried substr function. This is what I used in one of my previous project:
select * from orders
where to_char(my_timestamp,'hh24:mi:ss.FF3')
between '00:00:00.000' and '01:00:00.123';
Upvotes: 4
Reputation: 5941
Use TRUNC(my_timestamp, 'J')
to remove the hours and get only the '2013-08-15 00:00:00.00'.
So:
WHERE my_timestamp - TRUNC(my_timestamp, 'J') > 0
AND my_timestamp - TRUNC(my_timestamp, 'J') < 1/24 ;
Upvotes: 1