convert minutes to hh/mi/ss format in oracle query - oracle

I want to know the query which converts minutes to the format of hh/mi/ss in Oracle.I 've already seen lot of same questions from many forums but nothing helped me to get the exact result.
The query I used -Select to_char(to_date(mod(100,60),'mi'),'hh/mi/ss') from dual;
But I don't know how to get the hour value.Because mod function returns only the remainder I don't know how to take the quotient part and substitute into the hour field.

I suppose there are two ways of storing "minutes" in an Oracle database - you can either store them in a field whose datatype is INTERVAL DAY TO SECOND, or you can store them in a NUMBER. The simplest case to handle is the INTERVAL - in this case, the TO_CHAR function converts the value to a string of the form SDD HH:MM:SS.FFFFFF, where 'S' is sign ('+' or '-' as intervals can be positive or negative), DD = days, HH= hours, 'MM' = minutes, 'SS' = seconds, and 'FFFFFF' = fractions; thus, to get the HH:MI:SS all we need to do is use the SUBSTR function, as in
SUBSTR(TO_CHAR(I_VAL), 5, 8)
where I_VAL is an INTERVAL DAY TO SECOND value.
If the value to be converted is in a numeric field it gets a bit messy as we have to compute the individual field values, then subtract the previous fields as part of getting the next field. However, since the value stored is in minutes instead of seconds it's not particularly difficult:
create table TST (N_VAL NUMBER,
I_VAL INTERVAL DAY TO SECOND);
INSERT INTO TST(N_VAL, I_VAL) VALUES (666, INTERVAL '666' MINUTE);
SELECT N_VAL,
TRUNC(N_VAL/60) AS HOURS,
N_VAL-(TRUNC(N_VAL/60) * 60) AS MINUTES,
0 AS SECONDS,
TO_CHAR(I_VAL),
SUBSTR(TO_CHAR(I_VAL), 5, 8) AS HMS_FROM_INTERVAL
FROM TST;
SQLFiddle here
Best of luck.

Related

Is there a functon similar to DateDiff in MonetDB which can calculate number of weeks between two dates

Consider two dates, "01-Jan-2011' & '01-Oct-2011'.
I wish to calculate number of weeks in between these dates.
I have tried the following:
select extract ( week from ( (current_date+ interval '5' day) - current_date ));
It returns error " no such unary operator 'week(day_interval)'"
I am able to find number of days by using following :
select extract ( day from ( (current_date+ interval '5' day) - current_date ));
the line above returns the output
Is there any way I can achieve the same?
Further, MonetDB considers week from Monday to Sunday(1-7). Is there any way this can be updated/ customised to Sunday to Saturday.
Thanks.
There are a couple of possibilities that I can think of:
select date '2011-10-01' - date '2011-01-01';
results in a INTERVAL DAY value, actually expressed in seconds of the difference, i.e. 23587200.000. This you could divide by (72460*60), i.e. the number of seconds in a week. But it's still an INTERVAL type, not an INTEGER.
Another way is to first convert the date to integers: the number of seconds since "the epoch" (Jan 1, 1970):
select epoch_ms(date '2011-10-01');
This actually give milliseconds since the epoch, so an extra factor of 1000.
This result you can then manipulate to get what you want:
select (epoch_ms(date '2021-02-02') - epoch_ms(date '2020-12-31')) / (7*24*60*60*1000);
This results in a HUGEINT value (if you have 128 bit integers in your system, i.e. anything compiled with GCC or CLANG), so you can convert this to INTEGER:
select cast((epoch_ms(date '2011-10-01') - epoch_ms(date '2011-01-01')) / (7*24*60*60*1000) as integer);

convert from time in format h.mm to minutes

I have time stored as number in an oracle database in the format hh.mm, I want to calculate the sum and then write it back in another column in the same format hh.mm using a store procedure.
Is there any function in oracle for this type of summation or I have to do it from scratch?
Thanks in advance.
You are storing values in a custom format. So obviously Oracle won't a built-in function to handle it.
Doing this requires a series of steps, which could be wrapped into a user-defined function.
Convert the numeric column into a string. It is important to specify the format mask, otherwise the next step will produce the wrong result
Use regular expressions to extract the hour and minute values from the column
Derive the total number of minutes with simple arithmetic
Derive the new total number of hours and remainder of minutes with simple arithmetic
Derive the final number as a pseudo-decimal value.
Here is the SQL ...
select hh + (mi/100) as final_result
from (
select trunc(step3.tot_mins/60) as hh
, step3.tot_mins - (trunc(step3.tot_mins/60)*60) as mi
from (
select sum((step2.hh*60)+step2.mi) as tot_mins
from (
with step1 as (select to_char(ctime, '00000000000.99') ctime
from your_table)
select to_number(regexp_substr(ctime, '([0-9]+)', 1,1)) as hh
, to_number(regexp_substr(ctime, '([0-9]+)', 1, 2)) as mi
from step1
) step2
) step3
) step4
/
... and here is the obligatory SQL Fiddle.

ORA-01873: the leading precision of the interval is too small

When I try to query differences between 2 timestamps in Oracle, the result returns the interval normally.
select NVL2(ERROR_OUT_TS, ERROR_OUT_TS-ERROR_IN_TS, null) from table
or
select interval '8 00:00:10' day to second from dual
But when I try to select rows with greater than some interval, Oracle give me this error.
where ERROR_OUT_TS - ERROR_IN_TS <= '00 00:02:00'
or
where ERROR_OUT_TS - ERROR_IN_TS >= interval '0 00:00:10' day to second
It keeps saying that "the leading precision is too small".
I am trying to return the interval like 0 00:00:00:000
It is working fine for other customers. Only few customers are experiencing it.
How to choose the correct precision?
Try:
select interval '8 00:00:10' day(4) to second(4) from dual;
What it does is that 'day' and 'second' are default 2 digits, this expands them to accept 4. You probably just need 3 though.

Selecting the minimum difference between two dates in Oracle when the dates are represented as UNIX timestamps

There are many question posted about getting the difference between two dates in Oracle. My question is requires the query to do a couple more things.
Here's how far I have got at the moment
select m_bug_t.date_submitted, m_bug_history_t.date_modified
from m_bug_t, m_bug_history_t
where m_bug_t.id = m_bug_history_t.bug_id
and field_name = 'status'
and new_value = '100'
So far I get a set of date pairs returned like this
date_submitted | date_modified
1314894774 | 1315906468
...
...
I want to convert these numbers to dates, find the difference between them and then get the minimum of all the results. I want the difference to be represented as days.
Any ideas how you do this?
Thanks very much :).
Well, Unix timestamps are expressed as a number of seconds since 01 Jan 1970, so if you subtract one from the other you get the difference in seconds. The difference in days is then simply a matter of dividing by the number of seconds in a day:
(date_modified - date_submitted) / (24*60*60)
or
(date_modified - date_submitted) / 86400
To convert UNIX time to a date you can use:
DATE '1970-01-01' + numtodsinterval(:unix_time_stamp, 'second')
In SQL when you substract two dates you will get the difference in days so you could write:
SELECT MIN(dt_mod - dt_sub)
FROM (SELECT DATE '1970-01-01'
+ numtodsinterval(m_bug_t.date_submitted, 'second') dt_sub,
DATE '1970-01-01'
+ numtodsinterval(m_bug_history_t.date_modified, 'second') dt_mod
FROM m_bug_t, m_bug_history_t
WHERE m_bug_t.id = m_bug_history_t.bug_id
AND field_name = 'status'
AND new_value = '100')
Of course as others have suggested you don't really need to do this DATE conversion, you could just substract your 2 timestamps (difference in seconds) and convert the result in days.

Safe INTERVAL arithmetic

This query works withour errors
select add_months(date '2011-01-31', 1) from dual;
, while this one:
select date '2011-01-31' + interval '1' month from dual;
returns
ORA-01839: date not valid for month specified
So is there any safe way to add interval using INTERVAL literal?
This follows ANSI-specified behavior1 of adding INTERVALs to dates. This is also documented here:
When interval calculations return a datetime value, the result must be an actual datetime value or the database returns an error. For example, the next two statements return errors:
SELECT TO_DATE('31-AUG-2004','DD-MON-YYYY') + TO_YMINTERVAL('0-1') FROM DUAL;
SELECT TO_DATE('29-FEB-2004','DD-MON-YYYY') + TO_YMINTERVAL('1-0') FROM DUAL;
The function ADD_MONTHS on the other hand will just give you the last day of the month if the resulting month has less days - and I believe this function was created to address this issue.
1 http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt
b) Arithmetic is performed so as to maintain the integrity of
the datetime data type that is the result of the <datetime
value expression>. This may involve carry from or to the
immediately next more significant <datetime field>. If the
data type of the <datetime value expression> is TIME, then
arithmetic on the HOUR <datetime field> is undertaken modulo
24. If the <interval value expression> or <interval term> is
a year-month interval, then the DAY field of the result is
the same as the DAY field of the <datetime term> or <datetime
value expression>.
c) If, after the preceding step, any <datetime field> of the
result is outside the permissible range of values for the
field or the result is invalid based on the natural rules for
dates and times, then an exception condition is raised: data
exception-datetime field overflow.

Resources