how to get sum of time as float - sql

A table has a time column in float datatype is given as:
40m
11m
2m
0m
3m
1m
1m
How can I sum these values to get it in hours and minutes?

You could use Gordon's answer, which directly leverages SQL Server's built in time ability. An alternative would be the "brute force" approach of computing the number of hours and minutes represented by the sum of your time column:
WITH cte AS (
-- strip off 'm' units and convert to numbers
SELECT CONVERT(int, REPLACE(time, 'm', '')) AS time
FROM yourTable
)
SELECT
CONVERT(varchar(10), FLOOR(SUM(time) / 60)) + ':' +
CONVERT(varchar(10), FLOOR(SUM(time) % 60)) AS timestamp
FROM cte;
Demo
The demo shows that the logic holds up even if the number of minutes in your column should exceed 24 hours.

You can use dateadd() and then cast the result back to a time:
select cast(dateadd(minute, sum(col), 0) as time)
from t;
Note: This only works up to 23:59:00. The SQL Server time type does not support larger values.
Here is a rextester.

Related

Convert duration string into seconds integer

I want to turn strings that represent durations into their duration in seconds as an integer.
All of the strings are formatted in the following way:
hh:mm:ss
I was working with substrings, which I cast to integers and then multiplied with 3600, 60 or 1 respectively and in the end summed everything up.
Just like this:
SELECT
cast(substr(time_string, 1, 2) as smallint) * 3600 + cast(substr(time_string, 4, 2) as smallint) * 60 + cast(substr(time_string, 7, 2) as smallint) as seconds
from table_name
As I have to do this for multiple fields, I would be interested in a better way to achieve this result. My search for a better solution, though, fell flat so far.
I would appreciate any input or help!
Try using date_parse, cast to time and use date_diff with required unit:
select date_diff(
'second',
time '00:00:00', -- zero time
cast(date_parse('12:10:56', '%T') as time)
) seconds
Output:
seconds
43856

Calculate sum of duration SQL

I use the following sql to calculate the duration in the first query.
CDate(TimeSerial(Val([EndTime])\100,Val([EndTime]) Mod 100,0)-TimeSerial(Val([StartTime])\100,Val([StartTime]) Mod 100,0))) AS Duration
And get the following which is good
And now, I would like to further calculate the total time of different lessons within a week in another query. Something like sum(iif(lesson="math",duration,0))
But since it's time data type sql server doesn't let me use the sum function.
I tried the following sql.
sum(hour(duration) + minute(duration)) AS Total_time
But it isn't what I expect because I would like to keep the original format with some criteria.
Is there a neat way to do so? Thank you.
First, just get the numeric duration:
TimeSerial(Val([EndTime])\100,Val([EndTime]) Mod 100,0)-TimeSerial(Val([StartTime])\100,Val([StartTime]) Mod 100,0) AS Duration
This you can sum and convert to DateTime:
CDate(Sum([duration])) AS Total_time
Example:
Data:
Queries:
SELECT
StartTime,
EndTime,
TimeSerial(Val([EndTime])\100,Val([EndTime]) Mod 100,0)-TimeSerial(Val([StartTime])\100,Val([StartTime]) Mod 100,0) AS Duration
FROM
tTest;
SELECT
Count(*) AS Slots,
CDate(Sum([Duration])) AS TotalHours
FROM
qTest;
Result:
I would recommend just accepting the total time in seconds or decimal hours:
select datediff("s", starttime, endtime) as diff_seconds,
datediff("s", starttime, endtime) / (60 * 60.0) as diff_hours

Converting Between HubSpot Unix Timestamp and SQL DateTime

I am getting and posting data between HubSpot and my database.
HubSpot hold DateTime as UNIX Milliseconds and I am having trouble getting the same value when converting too and from.
(I want to store it as DateTime in my database which is why I am converting between them)
Starting value from HubSpot: 1531316462651
--FROM UNIX Starting Value TO DATETIME (This seems fine and gives me the value I would expect)
SELECT DATEADD(S, 1533046489401 / 1000, '1970-01-01T00:00:00.000')
--TO UNIX Starting Value FROM DATETIME (This doesn't give me the starting value - need help)
SELECT CAST(DATEDIFF(S, '1970-01-01T00:00:00.000', '2018-07-31 14:14:49.000') AS BIGINT) * 1000
As you can see when converting to unix from datetime, it is a different value to what I started with. I might be missing something obvious from looking at this too long (SQL Blindness I call it). Hopefully a simple resolve for someone who has done this before.
Thanks in advance.
EDIT: So I changed the first select statement and second statement so it reads like this:
--FROM UNIX TO DATETIME
SELECT DATEADD(MILLISECOND, 1531316462651 % 1000, DATEADD(SECOND, 1531316462651 / 1000, '19700101'))
--TO UNIX FROM DATETIME
SELECT (CAST(DATEDIFF(day, '1970-01-01T00:00:00.000', '2018-07-11 13:41:02.650') AS BIGINT) * 24 * 60 * 60 * 1000 +
DATEDIFF(millisecond, CAST('2018-07-11 13:41:02.650' as DATE), '2018-07-11 13:41:02.650')
)
Both return ALMOST the same value (1 Millisecond out) and I believe that is because SQL datetime rounds milliseconds in 3. So my original value 651 gets rounded to 650 when going to a datetime. I don't know how I can resolve this in SQL if anyone can help?
Microsoft has recognized this problem and created a function to solve it, DATEDIFF_BIG(). This is available since version 2016.
Before that, you need to do more complex manipulations. I think this does what you want:
SELECT (CAST(DATEDIFF(day, '1970-01-01T00:00:00.000', '2018-07-31 14:14:49.000') AS BIGINT) * 24 * 60 * 60 * 1000 +
DATEDIFF(millisecond, CAST('2018-07-31 14:14:49.000' as DATE), '2018-07-31 14:14:49.000')
)
That is, extract the days, multiply, and then extract the milliseconds from today. A day has 86,400,400 milliseconds, so this easily fits in an integer.
To get your original value, you need milliseconds in your date/time:
SELECT (CAST(DATEDIFF(day, '1970-01-01T00:00:00.000', '2018-07-31 14:14:49.000') AS BIGINT) * 24 * 60 * 60 * 1000 +
DATEDIFF(millisecond, CAST('2018-07-31 14:14:49.401' as DATE), '2018-07-31 14:14:49.401')
)

Show average difference between two time fields as MM:SS in SQL

I am using SQL Server 2008. I have several rows of start_time and end_time. I want to calculate the average difference between these two times in a MM:SS format.
start_time | end_time
10:15:30 | 10:15:45
10:45:00 | 10:47:30
Row 1 would be a difference of 00:15, and row 2 would be a difference of 02:30. The average of the entire dataset would be 01:23 (1 minute and 23 seconds).
The code I'm using looks like the following, but only returns an integer.
AVG(DATEDIFF(MI,start_time,end_time))
Thanks in advance for your help.
You're close, but you should use DateDiff() to get the average number of seconds between the two fields, rather than the average number of minutes.
With SQL Server 2008 R2, you don't have access to TIMEFROMPARTS() which would simplify the display greatly, so you'll have to convert this into a VARCHAR to get the format you want.
;With AverageSeconds As
(
Select Avg(DateDiff(Second, Start_Time, End_Time))) AvgSec
From YourTable
)
Select Right('00' + Convert(Varchar, (AvgSec / 60)), 2)
+ ':'
+ Right('00' + Convert(Varchar, (AvgSec % 60)), 2)
From AverageSeconds
You can convert the dates in unixtimestamp and then convert the seconds in a string.
Alternatively
right(convert(varchar(20), Dateadd(second, Avg(Datediff(second, Start_Time, End_Time)), 0), 120), 5)

How to Sum (Time(n)) in Sql Server?

How want to use the sum of the time(n) operator so that i can calculate the overall total of the time but Sql server saying can't add the Time(n) column
i have a casted column which contain difference of two dates, and being casted as Time(n) by me. Now i want to add those column to get how much time i had used in total How much hours minute and seconds so i apply
select Sum(cast ((date1-date2) as Time(0))) from ABC_tbl
where date1 is reaching time and date2 is startingtime in Date format and i want to total of all hours
Convert the time to an integer value before you sum it (for example, seconds):
SELECT SUM(
datediff(second, '00:00:00', [TimeCol])
)
FROM
...
Replace [TimeCol] with the name of the Time(n) column. This gives you the total time in seconds, which you can then easily convert to minutes, hours, etc...
Hope this example help you.
DECLARE #A TABLE (SD TIME(0),ED TIME(0))
INSERT INTO #A VALUES
('09:01:09','17:59:09'),
('09:08:09','16:10:09'),
('08:55:05','18:00:00')
SELECT SUM(DATEDIFF(MINUTE,SD,ED)) SUM_IN_MINUTES,
SUM(DATEDIFF(HOUR,SD,ED)) SUM_IN_HOURS
FROM #A
Result:
SUM_IN_MINUTES | SUM_IN_HOURS
---------------------------------------
1505 | 25
select Sum(DATEDIFF(Minute,date1,date2)) AS TIME from ABC_tbl
u have to calculate the date difference with DATEDIFF function then use SUM function to calculate your sum of time.
you can change Minute to Second-Hour-month etc..
Try this:
DECLARE
#MidnightTime TIME = '00:00:00.0000000',
#MidnightDateTime DATETIME2 = '0001-01-01 00:00:00.0000000';
SELECT SumOfTime = DATEADD(SECOND, SUM ( DATEDIFF(SECOND, #MidnightTime, x.Col1) ), #MidnightDateTime)
FROM (VALUES
(1, CONVERT(TIME, '10:10:10.0000001')),
(2, CONVERT(TIME, '00:00:05.0000002')),
(3, CONVERT(TIME, '23:59:59.0000003'))
) x(ID, Col1)
/*
SumOfTime
---------------------------
0001-01-02 10:10:14.0000000 = 1 day (!), 10 hours, 10 minutes, 14 seconds
*/
Note: instead of SECOND you could use another precision: MINUTE, HOUR or ... NANOSECOND (see section Arguments > datepart). Using a higher precision could leads to Arithmetic overflow errors (use CONVERT(BIGINT|NUMERIC(...,0), ...).
Note #2: because the precision is SECOND the result (SumOfTime) has 0000000 nanoseconds.