If I have a table with a column representing minutes, how can I convert those to hours and minutes?
For example, if I have in a cell "70" to be shown in the select "1h 10min", "60" to be shown "1h", etc.
I would suggest returning two derived fields in one query, the first one to get hours (through division), the second one to get minutes (through modulo operator). Try this:
select
minutes / 60 as h,
minutes % 60 as m
from
minutes
And here's a SQLFiddle.
EDIT
The following shows how the result could be formatted, too. I also updated the fiddle:
select
minutes / 60 as h,
minutes % 60 as m,
cast(minutes / 60 as text) || 'h ' || cast(minutes % 60 as text) || 'min' as formatted
from
minutes
Maybe you want to add some conditions to only show hours or minutes greater 0.
Related
I have a list of hours, showing like this
2.52 (meaning 2hours 52 minutes)
3
3.63
3.33
2.94
2.52
How can I convert this to # of minutes?
I have a list of hours, showing like this 2.52 (meaning 2hours 52
minutes)
If the scale part shows the minutes, we should directly add it directly to the total minutes:
select col, TRUNC(col) * 60 + (col % 1 * 100) minutes
from values (3.63),(2.94) tmp(col);
If they are the percentage of the hour (which makes more sense), then this can give you the result:
select col, TRUNC(col) * 60 + round(col % 1 * 60) minutes
from values (3.63),(2.94) tmp(col);
I dont understand the value of "2.94" - why is it 2 hours and 94 minutes and not 3.34, which would be the same amount of overall minutes?
Based on above assumption, you can use POSITION and SUBSTRING to split the string into the hour- and minute-part and then do the maths. First part of below query is extracting the left side of the dot and is multiplying it with 60, second part is just putting the minutes on top.
WITH hours AS (SELECT 3.63 as hour_value UNION SELECT 3.33 UNION SELECT 2.94)
select substr(hour_value, 0, position('.' in hour_value))*60 + substr(hour_value,position('.' in hour_value)+1) from hours;
In case the right side of the dot is NOT minutes, but the percentage of the whole hour, then you could just go with
select hour_value*60 from hours;
Using TIME_FROM_PARTS:
SELECT col, TIME_FROM_PARTS(FLOOR(col), col % 1 * 60, 0)
FROM tab;
Sample:
3.33
FLOOR(3.33) -> 3h
3.33 % 1 * 60 -> 0.33 * 60 -> 20 min
I have a column 'Duration' it holds the time the therapist spent with the client.
This is always entered as minutes so if the time was 3 hours it is entered as 180. I would like to set this in the query as 3.
This is how it is reporting from a canned report: Total duration time is the entered column, it is
defined as int,null. I would like to make this calculation and formatiing, in the sql for the shown column 'total duration'.
total_duration_num total_duration
10 0:10
120 2:00
30 0:30
5 0:05
60 1:00
One means of achieving this is to use:
the floor function to round down when dividing the minutes by 60 (for whole hours)
the mod function to get the remaining number of minutes after putting however many can fit into "whole" 60-minute hours
the lpad function to put a leading zero before that number of minutes, if <10, so that you see :05 rather than :5 for example
The query would look like this:
select duration,
concat( floor(duration/60) , ':' , lpad(mod(duration,60),2,'0') ) as hrs_mins
from duration_table;
This is a demonstration:
http://sqlfiddle.com/#!9/a52b6c/1/0
So i am putting the sql code in that i have shown below and my output that i get from the ProcessEnd minus ProcessStart is the duration time which comes out as "0 0:0:8.135". However, i need it to only show in terms of minutes, i don't want the hours or seconds, just the minutes the process runs.
TO_CHAR(rh.PROCESSSTART,'DD-MM-YYYY HH24:MI:SS') AS "PROCESSSTART",
TO_CHAR(rh.PROCESSEND,'DD-MM-YYYY HH24:MI:SS') AS "PROCESSEND",
(rh.PROCESSEND - rh.PROCESSSTART) AS "DURATION",
"0 0:0:8.135"
It looks that PROCESSEND and PROCESSSTART are DATEs.
If so, subtracting them results in number of days.
In order to get number of minutes, you'll have to multiply number of days by
24, as there are 24 hours in a day
60, as there are 60 minutes in an hour
so the final result would be
(rh.processend - rh.processstart) * 24 * 60 as number_of_minutes
I need random interval time between 0 and (10 days and 5 hours).
My code:
select random() * (interval '10 days 5 hours')
from generate_series(1, 50)
It works like should, except a few strange results, like:
0 years 0 mons 7 days 26 hours 10 mins 1.353353 secs
The problem is 26 hours, it shouldn't be more than 23. And I never get 10 days, what I'd like to.
Intervals in Postgres are quite flexible, so hour values of greater than 23 do not necessarily roll over to days. Use jusify_interval() to return them to the normal "days" and "hours"."
So:
select justify_interval(random() * interval '10 day 5 hour')
from generate_series(1, 200)
order by 1 desc;
will return values with appropriate values for days, hours, minutes, and seconds.
Now, why aren't you getting intervals with more than 10 days? This is simple randomness. If you increase the number of rows to 200 (as above), you'll see them (in all likelihood). If you run the code multiple times, sometimes you'll see none in that range; sometimes you'll see two.
Why? You are asking how often you get a value of 240+ in a range of 245. Those top 5 hours account for 0.02% of the range (about 1/50). In other words a sample of 50 is not big enough -- any given sample of 50 random values is likely to be missing 1 or more 5 hour ranges.
Plus, without justify_interval(), you are likely to miss those anyway because they may show up as 9 days with an hours component larger than 23.
Try this:
select justify_hours(random() * (interval '245 hours'))
FROM generate_series(1, 50)
See Postgres Documentation for an explanation of the justify_* functions.
One option would be to use an interval of one hour, and then multiply by the random number between 0 and 1 coming from the series:
select random() * 245 * interval '1 hour'
from generate_series(1, 50);
I can see that the other answers suggest using justify_interval. If you just want a series of intervals between 0 and 245 hours (245 hours corresponding to 10 days and 5 hours), then my answer should suffice.
I have the following formula to convert the duration into hours. I want to do case where any duration which is 15 min or more Is considered as an hour. for instance 1 hour 15 min will be calculated as 2 hrs, 2 hrs 15 min will be calculated as 3 hrs and so on. if it is less than 15 min after an hour than it will be the hour. eg 1 hr 5 min will be considered 1 hour.
((Case T0.DurType when 'M' then (T0.Duration/100)/.60 when 'D' then (T0.Duration*8) Else T0.Duration End)) as 'Duration'
Are you doing this in SQL or as a formula field in Crystal?
Is case syntax required for some reason, or is that simply the approach you initially chose?
What unit of time does each increment of Duration represent, 1 second, 1 minute?
Assuming the following:
this is in sql
case syntax is not required
each increment of Duration is 1 minute
Then here is your correct formula, using ceiling rather than case:
ceiling(T0.Duration/60) as "Duration"
That will increment any partial decimal value to the next highest integer, e.g., 75 minutes / 60 = 1.25 hours, and ceiling will increment to 2. 180 minutes / 60 = 3.00 hours and ceiling will output 3.
EDIT:
I'm not sure what you mean by achieving it in sql & crystal... if you calculate it in sql, it's passed to Crystal and won't need any further transformation. Either way, here's both solutions:
Crystal: Assumes minutes are used. the "\" operator is integer division, so the decimal is dropped. A simple if/then/else iif is used to add either 1 or zero if the remainder minutes are 15 or more:
MINUTES \ 60 + IIF (MINUTES mod 60 >= 15,1 , 0)
In SQL (MySQL syntax, MSSQL/TSQL may vary) achieves the same as follows:
floor(MINUTES / 60) + IF( (MINUTES % 60) >= 15,1 , 0)