Converting time intervals to HH:MI am/pm format using SQL - sql

My requirement is to convert 15 minute time intervals into HH:MI am/pm format using SQL. Giving an example:
IF interval = 0 => time = 12:00 am
IF interval = 15 => time = 12:15 am
IF interval = 30 => time = 12:30 am
IF interval = 45 => time = 12:45 am
IF interval = 60 => time = 01:00 am
and so on.,
So far, I've only managed to get the hourly intervals converted to HH:MI a/p format i.e. 12:00a, 01:00a etc., Here's a sample of the query that I'm using against my custom table.
START_TIME is the column containing the 15 minute interval entries.
select START_TIME/15,
case when (mod(START_TIME/15,4) = 0) then
case when (mod(START_TIME/15, 48) = 0) then (decode(START_TIME/15,0,'12:00 am',48,'12:00 pm'))
else (
case when (START_TIME/15 < 48) then (START_TIME/ 60 || 'am')
else (START_TIME / 60 - 12 || 'pm')
end
)
end
else ' '
end from MY_TABLE;
Can someone help me get it to work for all 15 min intervals? Thanks.

Try letting oracle do the time adding for you.
By default adding one to a date adds a single day. You want to add the time in your start_time column.
We will start with a date with no time component using TRUNC.
SELECT TRUNC(SYSDATE) FROM DUAL;
Then add 1/(60*24) * START_TIME minutes to this date and print out only the time portion of the date.
select TO_CHAR (TRUNC(SYSDATE) + (1/(60*24) * START_TIME), 'HH:MI AM')
from MY_TABLE

Maybe I don't understand your problem. Oracle interval types already do this.
The purpose of intervals in Oracle are to store time offsets and to allow you to do what you seem to be asking. An interval can be added to a base date/timestamp to produce a new date/timestamp and formatted in any format use date/time formatting functions with TO_CHAR and TO_DATE.
create table intervals(base_time timestamp, offset_interval interval);
SQL> desc intervals
Name Null? Type
----------------------------------------- -------- ----------------------------
BASE_TIME TIMESTAMP(6)
OFFSET_INTERVAL INTERVAL DAY(2) TO SECOND(6)
SQL> insert into intervals values(sysdate, interval '15' minute);
1 row created.
SQL> insert into intervals values(sysdate, interval '30' minute);
1 row created.
SQL> insert into intervals values(sysdate, interval '45' minute);
1 row created.
SQL> insert into intervals values(sysdate, interval '60' minute);
1 row created.
SQL> insert into intervals values(sysdate, interval '90' minute);
1 row created.
SQL> insert into intervals values(sysdate, interval '120' minute);
1 row created.
And then add the base timestamp to the interval, and format with TO_CHAR()
SQL> select to_char(base_time + offset_interval, 'HH:MI AM') from intervals;
TO_CHAR(
--------
03:45 PM
04:00 PM
04:15 PM
04:30 PM
05:00 PM
05:30 PM
6 rows selected.

Related

sysdate range to whole value

Is it possible to turn the current time stamp to a whole number?
Example: If sysdate returns 1/19/2022 5:36:49 PM can I turn that to 1/19/2022 5PM since it falls in the 5PM range.
Here is my query
Select FACILITY, TRK_ID, LOT_DTTM, IN_QTY
from TRK_ID_LOT
WHERE facility in 'DP1DM5'
and trk_id like ('AE%')
and lot_dttm > sysdate - 1
EXAMPLE:
Truncate it to hours:
SQL> select trunc(to_date('1/19/2022 5:36:49 PM', 'mm/dd/yyyy hh:mi:ss pm'), 'hh') res
2 from dual;
RES
----------------------
01/19/2022 05:00:00 PM
SQL>
If you want to update rows, do so using the same function:
update your_table set
date_column = trunc(date_column, 'hh');

get time series in 10 minutes of interval

I am generating one time-series from using below query.
SELECT date_trunc('min', dd):: TIMESTAMP WITHOUT TIME zone as time_ent
FROM generate_series ( timestamp '2021-12-09 06:34:37' + ((DATE_PART('min', timestamp '2021-12-09 06:34:37')::integer % 2) || ' minutes') :: INTERVAL
, '2021-12-10 06:34:37'::timestamp
, '20 min'::interval) dd
and it will give me output like below.
2021-12-09 06:34:00.000
2021-12-09 06:54:00.000
2021-12-09 07:14:00.000
2021-12-09 07:34:00.000
but I need output like.
2021-12-09 06:40:00.000
2021-12-09 07:00:00.000
2021-12-09 07:20:00.000
2021-12-09 07:40:00.000
currently, the time series hours depend upon the timestamp that I pass. in above it gives me mins like 34,54,14...but I want the mins like 40,00,20...it should not depend on the time I passed in query. I tried with timestamp '2021-12-09 06:34:37' + ((DATE_PART('min', timestamp '2021-12-09 06:34:37')::integer % 2) || ' minutes') :: INTERVAL but not any success.
Based on your description, I assumed that you want to create a series of timestamps for 00, 20, 40 minute at each hour until the next day.
select *
from (
select date_trunc('hour', current_timestamp) + i * interval '20 minutes' as ts
from generate_series(1, 24*3) as t(i)) t
where ts between current_timestamp and current_timestamp + interval '1 day'
The key idea here is to truncate the current_timestamp to 00 minute first. This becomes the start of the series. Then filter out the generated timestamps outside the range you want. You may need to adjust the second argument of generate_series function, depending on your requirement.
Or you can just generate a series of timestamp like the following:
select *
from (
select ts
from generate_series(
date_trunc('hour', current_timestamp),
current_timestamp + interval '1 day',
interval '20 minutes') as t(ts)) as t
where ts between current_timestamp and current_timestamp + interval '1 day'
Here, you still need to trunc your timestamp to hour first so the start of the series at 00 minute.

import data between specific times from consecutive days

In BIRT Report (which executes query for 10 minutes automatically - 24x7), I would like to report data of datatype "Timestamp", which I import from a table in oracle databank using query. Let's say I have a table with name "table 1". Table 1 contains a column with name "column1" of datatype timestamp. The data in column1 is from a machine which runs continuously (24x7 - 365 days).
Everyday in the report, I would like to present only 24 hours data, which is between 05:30:00 (present day) and 05:30:00 (next day).
SELECT column1 from table 1
WHERE coulmn1 = SYSDATE - INTERVAL '24' hour;
Extracting data of last 24 hours or days or months is easy, but how to define a logic in where statement, which takes the actual systemtime as a reference and provides data between 05:30 (present day) and 05:30 (next day).
For Example:
The automatic execution of query at 01:00:00 (or 1 AM) should show the data from previous day (05:30:00) to present (01:00:00)
The automatic executin of query at 08:00:00 (or 8 AM) should show the data from actual day (05:30:00 to 08:00:00).
Any help how to define a logic in where statement will be appreciated.
Use TRUNC(SYSDATE) to trunate it back to midnight and then add an INTERVAL:
SELECT column1
FROM table1
WHERE column1 >= TRUNC( SYSDATE ) + INTERVAL '0 05:30' DAY TO MINUTE
AND column1 < TRUNC( SYSDATE ) + INTERVAL '1 05:30' DAY TO MINUTE;
If you want to handle the case when the SYSDATE is before 05:30 then:
SELECT column1
FROM table1
WHERE column1 >= TRUNC( SYSDATE - INTERVAL '05:30' HOUR TO MINUTE )
+ INTERVAL '0 05:30' DAY TO MINUTE
AND column1 < TRUNC( SYSDATE - INTERVAL '05:30' HOUR TO MINUTE )
+ INTERVAL '1 05:30' DAY TO MINUTE;
And if you do not want to show future times then:
SELECT column1
FROM table1
WHERE column1 >= TRUNC( SYSDATE - INTERVAL '05:30' HOUR TO MINUTE )
+ INTERVAL '0 05:30' DAY TO MINUTE
AND column1 <= SYSTIMESTAMP;

How to create an Oracle date based on separate date and time components?

How can you create an Oracle DATE variable based on a date from a DATE column and a fixed string?
Ie: Use to_date with the date coming from mytable.date_col and the string being fixed at "05:30"?
You can convert to a string and back, ignoring any existing time part:
to_date(to_char(date_col, 'YYYY-MM-DD') || ' 05:30:00', 'YYYY-MM-DD HH24:MI:SS')
The to_char() gets just the date portion as a string, say '2015-04-15'. Your fixed time is then appended to that string, so it becomes '2015-04-15 05:30:00'. And that is then converted to a date, using a suitable matching format model.
Or take the date back to midnight using trunc() (assuming it may have a later time) and add the fraction of a day representing that time; which is 5.5 hours out of 24 hours so 5.5/24:
trunc(date_col) + 5.5/24
or the same thing with an interval:
trunc(date_col) + interval '0 05:30:00' day to second
Quick demo of all three:
with mytable (date_col) as (
select to_date('2016-04-15 15:16:17', 'YYYY-MM-DD HH24:MI:SS') from dual
)
select to_date(to_char(date_col, 'YYYY-MM-DD') || ' 05:30:00',
'YYYY-MM-DD HH24:MI:SS') as res1,
trunc(date_col) + 5.5/24 as res2,
trunc(date_col) + interval '0 05:30:00' day to second as res3
from mytable;
RES1 RES2 RES3
------------------- ------------------- -------------------
2016-04-15 05:30:00 2016-04-15 05:30:00 2016-04-15 05:30:00

Oracle Add 1 hour in SQL

I am just trying to add 1 hour to a value, it is kind of complicated on where and why i am doing this but basically i just need to query something like this
select DATE_ADD(hh,1,'2014-10-15 03:30:00 pm') from dual
I keep reading old articles that say to use dateAdd or date_add but I keep getting invalid identifier errors.
select sysdate + 1/24 from dual;
sysdate is a function without arguments which returns DATE type
+ 1/24 adds 1 hour to a date
select to_char(to_date('2014-10-15 03:30:00 pm', 'YYYY-MM-DD HH:MI:SS pm') + 1/24, 'YYYY-MM-DD HH:MI:SS pm') from dual;
Use an interval:
select some_date_column + interval '1' hour
from your_table;
You can use INTERVAL type or just add calculated number value - "1" is equal "1 day".
first way:
select date_column + INTERVAL '0 01:00:00' DAY TO SECOND from dual;
second way:
select date_column + 1/24 from dual;
First way is more convenient when you need to add a complicated value - for example, "1 day 3 hours 25 minutes 49 seconds".
See also: http://www.oracle-base.com/articles/misc/oracle-dates-timestamps-and-intervals.php
Also you have to remember that oracle have two interval types - DAY TO SECOND and YEAR TO MONTH.
As for me, one interval type would be better, but I hope people in oracle knows, what they do ;)
Old way:
SELECT DATE_COLUMN + 1 is adding a day
SELECT DATE_COLUMN + N /24 to add hour(s) - N being number of hours
SELECT DATE_COLUMN + N /1440 to add minute(s) - N being number of minutes
SELECT DATE_COLUMN + N /86400 to add second(s) - N being number of seconds
Using INTERVAL:
SELECT DATE_COLUMN + INTERVAL 'N' HOUR or MINUTE or SECOND - N being a number of hours or minutes or seconds.
To add/subtract from a DATE, you have 2 options :
Method #1 :
The easiest way is to use + and - to add/subtract days, hours, minutes, seconds, etc.. from a DATE, and ADD_MONTHS() function to add/subtract months and years from a DATE. Why ? That's because from days, you can get hours and any smaller unit (1 hour = 1/24 days), (1 minute = 1/1440 days), etc... But you cannot get months and years, as that depends on the month and year themselves, hence ADD_MONTHS() and no add_years(), because from months, you can get years (1 year = 12 months).
Let's try them :
SELECT TO_CHAR(SYSDATE, 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints current date: 19-OCT-2019 20:42:02
SELECT TO_CHAR((SYSDATE + 1/24), 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints date + 1 hour: 19-OCT-2019 21:42:02
SELECT TO_CHAR((SYSDATE + 1/1440), 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints date + 1 minute: 19-OCT-2019 20:43:02
SELECT TO_CHAR((SYSDATE + 1/86400), 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints date + 1 second: 19-OCT-2019 20:42:03
-- Same goes for subtraction.
SELECT SYSDATE FROM dual; -- prints current date: 19-OCT-19
SELECT ADD_MONTHS(SYSDATE, 1) FROM dual; -- prints date + 1 month: 19-NOV-19
SELECT ADD_MONTHS(SYSDATE, 12) FROM dual; -- prints date + 1 year: 19-OCT-20
SELECT ADD_MONTHS(SYSDATE, -3) FROM dual; -- prints date - 3 months: 19-JUL-19
Method #2 : Using INTERVALs, you can or subtract an interval (duration) from a date easily. More than that, you can combine to add or subtract multiple units at once (e.g 5 hours and 6 minutes, etc..)
Examples :
SELECT TO_CHAR(SYSDATE, 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints current date: 19-OCT-2019 21:34:15
SELECT TO_CHAR((SYSDATE + INTERVAL '1' HOUR), 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints date + 1 hour: 19-OCT-2019 22:34:15
SELECT TO_CHAR((SYSDATE + INTERVAL '1' MINUTE), 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints date + 1 minute: 19-OCT-2019 21:35:15
SELECT TO_CHAR((SYSDATE + INTERVAL '1' SECOND), 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints date + 1 second: 19-OCT-2019 21:34:16
SELECT TO_CHAR((SYSDATE + INTERVAL '01:05:00' HOUR TO SECOND), 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints date + 1 hour and 5 minutes: 19-OCT-2019 22:39:15
SELECT TO_CHAR((SYSDATE + INTERVAL '3 01' DAY TO HOUR), 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints date + 3 days and 1 hour: 22-OCT-2019 22:34:15
SELECT TO_CHAR((SYSDATE - INTERVAL '10-3' YEAR TO MONTH), 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints date - 10 years and 3 months: 19-JUL-2009 21:34:15
The calculation is simple
if you want to add 1 hour in the date .
every day have 24 hour , you can add .
select sysdate + 1/24 from dual;
if you want 1 day to add
select sysdate + 24/24 from dual;
or
select sysdate + 1 from dual;
same as for 2, 3 , 4 day
For static date you have the answer below.