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
Related
I'm struggling with this.
I have a column in Snowflake called DURATION, it is VARCHAR type.
The values include basically number in days, hours, minutes, seconds. The value could include either just the number with one unit of time (day or hour or minute or second) such as 3 hours or 14 minutes or 3 seconds or it could include the combination of either all units of time or a few such as 1 day 3 hours 35 minutes or 1 hour 9 minutes or 45 minutes 1 second.
The value could also be blank or invalid such as text or it could be indicating day, hour or minute but without a number (see the last 3 rows in the table below).
I would greatly appreciate it if you guys could help me with the following:
in SNOWFLAKE, convert all valid values to number type and normalize them to minutes (e.g. the resulted value for 7 Hours and 13 Minutes would be 433).
Thanks a lot, guys!
DURATION
1 Second
10 Seconds
1 Minute
3 Minutes
20 Minutes
1 Hour
2 Hours
7 Hours 13 Minutes
1 Hour 1 Minute
1 Day
1 Day 1 Hour
1 Day 1 Hour 1 Minute
1 Day 10 Hours
2 Days 1 Hour
3 Days 9 Hours
1 Day 3 Hours 45 Minutes
Duration (invalid)
Days
Day Minute
Minutes
I tried many things using regex_substr, try_to_number, coalesce functions in CASE statements but I'm getting either 0s or NULL for all values. Very frustrating
I think you would want to use STRTOK_TO_ARRAY in a CTE subquery or put into a temp table. Then you could use ARRAY_POSITION to find the labels and the index one less than the label should be the value. Those values could be put into separate columns with a case for each label pulling the found values. The case statements could be computed columns if you insert the results of the first query into a table. From there you can concatenate colons and cast to a time type and use datediff, or do the arithmetic to calculate the minutes.
I am creating a table which will have 2 columns:
Day_time (time from 1978-01-01 00:00:00 Sunday, till 1978-01-07 23:59:00.0 Saturday, Granularity: Minute)
Time_id (a unique id for each minute), to be populated
I have column one populated. I want to populate column two.
How I am doing it right now:
EXTRACT(dayofweek FROM day_time) * 10000 + DATEDIFF('minutes', TRUNC(day_time), day_time)
I basically want a function where I pass any date and it tells me where I am in a week. So, I need a function, just like the function above. Just more optimized, where I give a date and get a unique ID. The unique ID should repeat weekly.
Example: ID for Jan 1, 2015 00:00:00 will be same as Jan 8, 2015 00:00:00.
Why 1978-01-01? cuz it starts from a Sunday.
Why 10,000? cuz the number of minutes in a day are in four digits.
You can do it all in one fell swoop, without needing to extract the date separately:
SELECT DATEDIFF('minutes', date_trunc('week',day_time), day_time) which I'd expect to be marginally faster.
Another approach that I'd expect to be significantly faster would be converting the timestamp to epoch, dividing by 60 to get minutes from epoch and then taking the value modulus of 10,080 (for 60 * 24 * 7 minutes in a week).
SELECT (extract(epoch from day_time) / 60) % 10080
If you don't care about the size of the weekly index, you could also do:
SELECT (extract(epoch from day_time)) % 604800 and skip the division step altogether, which should make it faster still.
I have a table that lists activity for people and start / end timed for activity.
How do I get total amount of records for each person?
SELECT NAME,
--sum(startDT- endDT) AS minutes -- stuck here
FROM TABLE1
GROUP BY NAME
You're subtracting end time from start time, which will produce a negative value - try flipping those around (subtract start time from end time). The following will give you the number of records and the total elapsed time for each NAME:
SELECT NAME,
COUNT(*) AS "Records for NAME",
TO_CHAR(NUMTODSINTERVAL(SUM(END_DATE_TIME - START_DATE_TIME), 'DAY')) AS MINUTES
FROM TABLE1
GROUP BY NAME
SQLFiddle here
Share and enjoy.
Assuming that startDT and endDT are both of type date, you were really close. Subtracting two dates gives a difference in days. Multiply by 24 to get a difference in hours and again by 60 to get minutes
SELECT NAME,
sum(endDT - startDT)*24*60 AS minutes -- stuck here
FROM TABLE1
GROUP BY NAME
Assuming that your differences aren't always an exactly even number of minutes, you'll either get a non-integer result (e.g. 12.5 for 12 minutes 30 seconds) here or you'll want to either round or trunc the sum to get an integer number of minutes.
I am currently working on a Firebird database which stores slots for a time (like appointments). In the data the timeslot is stored in an Integer format but is not the slot time.
Example:
Slot Time: 11am
Database Value: 660
The database value is represented as the number of minutes since midnight. So 11am is 660 minutes from midnight. Or 12noon is 720
Question How, in Firebird, can a convert this 660 to display as 1100 (still an integer) or 540 as 900 (basically 9am)?
What you have stored into database is minutes since start of the day. So you just divide with 60 to get hours. Keep in mind that in SQL if both arguments of the division are integers you'll get integer as an answer, not decimal! Something like following should work for you (assuming the number of minutes is stored to timeslot field):
SELECT
cast(timeslot / 60 as varchar(2)) ||
case
when mod(timeslot, 60) < 10 then '0'|| mod(timeslot, 60)
else mod(timeslot, 60)
end
FROM t
This should give you 1130 for 11:30 am, not 1150 (11,5 hours).
Also see the DATEADD function.
First off I'd store it in the database as a TIME column instead of a number of minutes. Note that on a technical level Firebird stores TIME as the number of 100 microseconds since midnight. However if you really want to store as number of minutes, then you can use:
From minutes to TIME using DATEADD:
DATEADD(x MINUTE TO TIME'00:00')
Time to minutes using DATEDIFF:
DATEDIFF(MINUTE FROM TIME'00:00' TO y)
So:
SELECT
DATEADD(660 MINUTE TO TIME'00:00'),
DATEDIFF(MINUTE FROM TIME'00:00' TO TIME'11:00')
FROM RDB$DATABASE
Will return: 11:00:00.000, 660
I have a table with measures and the time this measures have been taken in the following form: MM/DD/YYYY HH:MI:SS AM. I have measures over many days starting at the same time every day.The datas are minute by minute so basically the seconds are always = 0. I want to select only the measures for the first 5 minutes of each day. I would have used the where statement but the condition would only be on the minutes and note the date is there a way to do this?
Thanks
You could try something like this:
SELECT * FROM SomeTable
WHERE
DATEPART(hh, timestamp_col) = 0 AND -- filter for first hour of the day
DATEPART(mm, timestamp_col) <= 5 -- filter for the first five minutes
Careful! 0 means midnight. If your "first hour" of the day is actually 8 or 9 AM then you should replace the 0 with an 8 or 9.