Convert non-standard mm:ss to hh:mm:ss with T-SQL - sql

I am doing some data clean up from an old, text-based system. The system tracks running time of films with a format like this: '86:08'.
This means 1 hour 26 minutes and 8 seconds.
I am able to convert the first part like this:
declare #t varchar(10)
set #t = '86:08'
select #t as t,
t2 = try_convert(time,format(dateadd(minute,cast(left(#t, 2) as int),0),'hh:mm','en-US'))
Result:
t t2
86:08 01:26:00.0000000
How can I get the seconds as well, so the result would be 01:26:08:0000?

You could recover the 2 rightmost digits and convert to seconds instead of minutes.
Consider:
try_convert(
time,
format(
dateadd(second,cast(left(#t, 2) as int)*60 + cast(right(#t, 2) as int), 0),
'hh:mm:ss','en-US')
)
Demo on DB Fiddle:
declare #t varchar(10)
set #t = '86:08'
select
#t as t,
t2 = try_convert(
time,
format(
dateadd(second,cast(left(#t, 2) as int)*60 + cast(right(#t, 2) as int), 0),
'hh:mm:ss','en-US')
)
GO
t | t2
:---- | :-------
86:08 | 01:26:08

Here you go:
You need to multiply out to milliseconds as the fractional part is discarded.
SELECT DATEADD(ms, 86.08 * 1000, 0)
If you want it without the date portion you can use CONVERT, with style 114
SELECT CONVERT(varchar, DATEADD(ms, 86.08 * 1000, 0), 114)

You can convert the value to seconds and back to a time:
select #t as t,
convert(time, dateadd(second, left(#t, 2) * 60 + right(#t, 2), 0))

Related

How to calculate the sum of time with SQL SERVER? [duplicate]

I have a column called "WrkHrs" and the data type is time(hh:mm:ss). I want to sum up the working hours for employees. But since it's time data type sql server doesn't let me use like sum(columnname).
How can I sum up the time data type fieled in sql query?
SELECT EmployeeID, minutes_worked = SUM(DATEDIFF(MINUTE, '0:00:00', WrkHrs))
FROM dbo.table
-- WHERE ...
GROUP BY EmployeeID;
You can format it pretty on the front end. Or in T-SQL:
;WITH w(e, mw) AS
(
SELECT EmployeeID, SUM(DATEDIFF(MINUTE, '0:00:00', WrkHrs))
FROM dbo.table
-- WHERE ...
GROUP BY EmployeeID
)
SELECT EmployeeID = e,
WrkHrs = RTRIM(mw/60) + ':' + RIGHT('0' + RTRIM(mw%60),2)
FROM w;
However, you're using the wrong data type. TIME is used to indicate a point in time, not an interval or duration. Wouldn't it make sense to store their work hours in two distinct columns, StartTime and EndTime?
In order to sum up the working hours for an employee you can calculate the difference between the shift start time and end time in minutes and convert it to readable format as following:
DECLARE #StartTime datetime = '08:00'
DECLARE #EndTime datetime = '10:47'
DECLARE #durMinutes int
DECLARE #duration nvarchar(5)
SET #durMinutes = DATEDIFF(MINUTE, #StartTime, #EndTime)
SET #duration =
(SELECT RIGHT('00' + CAST((#durMinutes / 60) AS VARCHAR(2)),2) + ':' +
RIGHT('00' + CAST((#durMinutes % 60) AS VARCHAR(2)), 2))
SELECT #duration
The result : 02:47
two hours and 47 minutes
select DATEDIFF(MINUTE, '0:00:00', '00:02:08')
results in :- 2
select DATEDIFF(SECOND, '0:00:00', '00:02:08')
results in :- 128
Using seconds gives a better answer.
So I think the answer can be
SELECT
EmployeeId
, seconds_worked = SUM (DATEDIFF (SECOND, '0:00:00', WrkHrs))
FROM
tbl_employee
GROUP BY
EmployeeId;
DECLARE #Tab TABLE
(
data CHAR(5)
)
INSERT #Tab
SELECT '25:30' UNION ALL
SELECT '31:45' UNION ALL
SELECT '16:00'
SELECT STUFF(CONVERT(CHAR(8), DATEADD(SECOND, theHours + theMinutes,
'19000101'), 8), 1, 2, CAST((theHours + theMinutes) / 3600 AS VARCHAR(12)))
FROM (
SELECT ABS(SUM(CASE CHARINDEX(':', data) WHEN 0 THEN 0 ELSE 3600 *
LEFT(data, CHARINDEX(':', data) - 1) END)) AS theHours,
ABS(SUM(CASE CHARINDEX(':', data) WHEN 0 THEN 0 ELSE 60 *
SUBSTRING(data, CHARINDEX(':', data) + 1, 2) END)) AS theMinutes
FROM #Tab
) AS d
For MS SQL Server, when your WorkingTime is stored as a time, or a varchar in order to sum it up you should consider that:
1) Time format is not supporting sum, so you need to parse it
2) 23:59:59.9999999 is the maximum value for the time.
So, the code that will work to get you the total number of WorkingHours:WorkingMinutes:WorkingSeconds would be the following:
SELECT
CAST(FORMAT((SUM((DATEPART("ss",WorkingTime) + DATEPART("mi",WorkingTime) * 60 + DATEPART("hh",WorkingTime) * 3600)) / 3600),'00') as varchar(max)) + ':' +
CAST(FORMAT((SUM((DATEPART("ss",WorkingTime) + DATEPART("mi",WorkingTime) * 60 + DATEPART("hh",WorkingTime) * 3600)) % 3600 / 60),'00') as varchar(max)) + ':' +
CAST(FORMAT((SUM((DATEPART("ss",WorkingTime) + DATEPART("mi",WorkingTime) * 60 + DATEPART("hh",WorkingTime) * 3600)) % 3600 % 60),'00') as varchar(max)) as WorkingTimeSum
FROM TableName
It must be as simple as that.
Steps
convert time to seconds
sum the RESULT
convert the sum to time
Eg:
take a case you might want to sum the following time:
| present_hours |
|-----------------|
| 00:01:20.000000 |
|-----------------|
| 00:01:13.000000 |
|-----------------|
| 00:01:45.000000 |
|-----------------|
| 00:01:03.000000 |
|-----------------|
| 00:01:10.000000 |
|-----------------|
| 00:00:56.000000 |
SELECT SEC_TO_TIME(SUM(TIME_TO_SEC(present_hours))) as total_present_hours FROM time_booking;

How to Find Time difference with hours, minutes and seconds (All Results) in SQL Server

How to Find Time difference with all conditions like
if difference only minutes
49 mintus
if a difference in Hour
1 hour 20 minutes
i am trying
SELECT DATEDIFF(MINUTE,'2018-08-09 10:16:49.000','2018-08-09 11:14:40.000') AS Diff
but this is only show in minutes
I have also tried this one
DECLARE #StartTime datetime = '2018-08-09 10:16:49.000',
#EndTime datetime = '2018-08-09 12:44:05.000'
SELECT CAST(#EndTime - #StartTime as Time) As TimeDiffere
output : 02:27:16.0000000
but I want to 2hr 27mins 16Sec
If your SQL-server version higher than 2012, you can try to sue format function.
CREATE TABLE T(
StartTime datetime,
EndTime datetime
);
insert into t values ('2018-08-09 10:16:49.000','2018-08-09 12:44:05.000')
Query 1:
SELECT format(EndTime - StartTime ,'hh\hr mm\min\s ss\Sec') As TimeDiffere
FROM T
Results:
| TimeDiffere |
|-------------------|
| 02hr 27mins 16Sec |
NOTE
Backslash \ can escape keyword from the format like hr,min,s..., then display it as the original word.
DECLARE #StartTime datetime = '2018-08-09 10:01:15.000',
#EndTime datetime = '2018-08-09 12:50:00.000'
SELECT CONCAT((DATEDIFF(second,#StartTime,#EndTime )/60)/60,'hr ',(DATEDIFF(second,#StartTime,#EndTime)/60)%60,'mins ',DATEDIFF(second,#StartTime,#EndTime)%60,'Sec')
As TimeDiffere
DECLARE #StartTime datetime = '2018-08-09 12:16:49.000',
#EndTime datetime = '2018-08-09 12:44:05.000'
select [hour] + [minute] + [second] as TimeDiffere
from (
select diff_sec = datediff(second, #StartTime, #EndTime)
) t
cross apply
(
select [hour] = isnull(convert(varchar(10), nullif(diff_sec / 60 / 60, 0))
+ ' hours ', '')
) hr
cross apply
(
select [minute] = isnull(convert(varchar(10), nullif(diff_sec / 60 % 60, 0))
+ ' mintues ', '')
) mn
cross apply
(
select [second] = isnull(convert(varchar(10), nullif(diff_sec % 60, 0))
+ ' seconds', '')
) sc
/* RESULT
27 mintues 16 seconds
*/
If you have a poor datetime functionality to get hh.mm.ss, then you can use apply :
select t.*, concat( (dtdiff / 3600), 'hr ', (dtdiff / 60) % 60, 'mins ', dtdiff % 60, 'sec')
from table t cross apply
( values (datediff(second, startdate, enddate))
) tt(dtdiff);

SQL conversion from varchar to datetime

One of the columns of my SQL Server table is mm:ss of varchar type where mm = minutes and ss = seconds.
I need to get the average of that column.
Should I convert that column to datetime format first? If so can you tell me how? If not can you tell me what I should do?
Here is my failed attempt to convert it to datetime :
SELECT CONVERT(DATETIME, '2014-01-01 '+Pace+':00', 108)
Where pace is a varchar like 23:05
If you want the average, I would convert the column to number of seconds and work with that:
select avg(pace_secs) as average_in_seconds
from (select cast(left(pace, 2) as int) * 60 + cast(right(pace, 2) as int) as pace_secs
from t
) t;
If you want this back in the format, then you can do:
select right('00' + cast(avg(pace_secs) / 60 as int), 2) + ':' +
right('00' + avg(page_secs) % 60), 2)
from (select cast(left(pace, 2) as int) * 60 + cast(right(pace, 2) as int) as pace_secs
from t
) t;
declare #pace varchar(20) = '23:05 ';
SELECT cast( '2014-01-01 '+cast(#pace as varchar(5))+':00' as datetime)
For SQL2012 and later
SELECT
FORMAT(DATEADD(second,AVG(DATEDIFF(second,0,'00:'+[Pace])),0),'mm:ss')
FROM MyTable

How to sum up time field in SQL Server

I have a column called "WrkHrs" and the data type is time(hh:mm:ss). I want to sum up the working hours for employees. But since it's time data type sql server doesn't let me use like sum(columnname).
How can I sum up the time data type fieled in sql query?
SELECT EmployeeID, minutes_worked = SUM(DATEDIFF(MINUTE, '0:00:00', WrkHrs))
FROM dbo.table
-- WHERE ...
GROUP BY EmployeeID;
You can format it pretty on the front end. Or in T-SQL:
;WITH w(e, mw) AS
(
SELECT EmployeeID, SUM(DATEDIFF(MINUTE, '0:00:00', WrkHrs))
FROM dbo.table
-- WHERE ...
GROUP BY EmployeeID
)
SELECT EmployeeID = e,
WrkHrs = RTRIM(mw/60) + ':' + RIGHT('0' + RTRIM(mw%60),2)
FROM w;
However, you're using the wrong data type. TIME is used to indicate a point in time, not an interval or duration. Wouldn't it make sense to store their work hours in two distinct columns, StartTime and EndTime?
In order to sum up the working hours for an employee you can calculate the difference between the shift start time and end time in minutes and convert it to readable format as following:
DECLARE #StartTime datetime = '08:00'
DECLARE #EndTime datetime = '10:47'
DECLARE #durMinutes int
DECLARE #duration nvarchar(5)
SET #durMinutes = DATEDIFF(MINUTE, #StartTime, #EndTime)
SET #duration =
(SELECT RIGHT('00' + CAST((#durMinutes / 60) AS VARCHAR(2)),2) + ':' +
RIGHT('00' + CAST((#durMinutes % 60) AS VARCHAR(2)), 2))
SELECT #duration
The result : 02:47
two hours and 47 minutes
select DATEDIFF(MINUTE, '0:00:00', '00:02:08')
results in :- 2
select DATEDIFF(SECOND, '0:00:00', '00:02:08')
results in :- 128
Using seconds gives a better answer.
So I think the answer can be
SELECT
EmployeeId
, seconds_worked = SUM (DATEDIFF (SECOND, '0:00:00', WrkHrs))
FROM
tbl_employee
GROUP BY
EmployeeId;
DECLARE #Tab TABLE
(
data CHAR(5)
)
INSERT #Tab
SELECT '25:30' UNION ALL
SELECT '31:45' UNION ALL
SELECT '16:00'
SELECT STUFF(CONVERT(CHAR(8), DATEADD(SECOND, theHours + theMinutes,
'19000101'), 8), 1, 2, CAST((theHours + theMinutes) / 3600 AS VARCHAR(12)))
FROM (
SELECT ABS(SUM(CASE CHARINDEX(':', data) WHEN 0 THEN 0 ELSE 3600 *
LEFT(data, CHARINDEX(':', data) - 1) END)) AS theHours,
ABS(SUM(CASE CHARINDEX(':', data) WHEN 0 THEN 0 ELSE 60 *
SUBSTRING(data, CHARINDEX(':', data) + 1, 2) END)) AS theMinutes
FROM #Tab
) AS d
For MS SQL Server, when your WorkingTime is stored as a time, or a varchar in order to sum it up you should consider that:
1) Time format is not supporting sum, so you need to parse it
2) 23:59:59.9999999 is the maximum value for the time.
So, the code that will work to get you the total number of WorkingHours:WorkingMinutes:WorkingSeconds would be the following:
SELECT
CAST(FORMAT((SUM((DATEPART("ss",WorkingTime) + DATEPART("mi",WorkingTime) * 60 + DATEPART("hh",WorkingTime) * 3600)) / 3600),'00') as varchar(max)) + ':' +
CAST(FORMAT((SUM((DATEPART("ss",WorkingTime) + DATEPART("mi",WorkingTime) * 60 + DATEPART("hh",WorkingTime) * 3600)) % 3600 / 60),'00') as varchar(max)) + ':' +
CAST(FORMAT((SUM((DATEPART("ss",WorkingTime) + DATEPART("mi",WorkingTime) * 60 + DATEPART("hh",WorkingTime) * 3600)) % 3600 % 60),'00') as varchar(max)) as WorkingTimeSum
FROM TableName
It must be as simple as that.
Steps
convert time to seconds
sum the RESULT
convert the sum to time
Eg:
take a case you might want to sum the following time:
| present_hours |
|-----------------|
| 00:01:20.000000 |
|-----------------|
| 00:01:13.000000 |
|-----------------|
| 00:01:45.000000 |
|-----------------|
| 00:01:03.000000 |
|-----------------|
| 00:01:10.000000 |
|-----------------|
| 00:00:56.000000 |
SELECT SEC_TO_TIME(SUM(TIME_TO_SEC(present_hours))) as total_present_hours FROM time_booking;

SUM minutes SQL server

HI guys,
My litle problem goes like this :
I have this columns : PHONE_NR , TIME ( time field ), Meaning the calling telephone number and call duration. I need to group phone nr and sum the minutes. Filds looks like this :
nr time
726028xxx 00:07:07
735560css 00:07:37
726028xxx 00:07:55
SELECT PHONE_NR, SUM(DATEPART(minute, TIME)) FROM [table] GROUP BY PHONE_NR;
As far as I know this should work for both SQL Server DATETIME and the 2008 TIME data-types.
Example:
DECLARE #tbl TABLE
(
phone_nr varchar(10),
call_time TIME
);
INSERT INTO #tbl VALUES ('726028xxx', '00:07:07');
INSERT INTO #tbl VALUES ('735560css', '00:07:37');
INSERT INTO #tbl VALUES ('726028xxx', '00:07:55');
SELECT phone_nr, SUM(DATEPART(minute, call_time)) AS total_call_time FROM #tbl GROUP BY phone_nr;
Results in:
phone_nr | minutes
726028xxx | 14
735560css | 7
EDIT:
This version is identical to the above, except it also takes into account the seconds and hours (e.g. 1hr 7min 07secs = 67.117 minutes) so it's much more accurate.
SELECT
phone_nr,
SUM(CAST(DATEPART(second, call_time) + (DATEPART(minute, call_time) * 60) + (DATEPART(hour, call_time) * 3600) AS decimal) / 60) AS total_call_time
FROM
#tbl
GROUP BY
phone_nr;
Results in the following if the first record was 01:07:07.
phone_nr | minutes
726028xxx | 75.033332
735560css | 7.616666
You can use DATEDIFF to get the total number of minutes that have passed since time "zero"
SELECT
[PHONE_NR],
SUM(DATEDIFF(minute, '00:00:00', [TIME]))
FROM
[YourTable]
GROUP BY
[PHONE_NR]
declare #v1 varchar(50)
declare #v2 varchar(50)
set #v1='03:10'
set #v2='01:50'
--select cast(left(v1,2) as int) + cast(left(v2,2)as int)
select
cast(
cast(left(#v1,2) as int) + cast(left(#v2,2)as int)
+(cast(right(#v1,2) as int) + cast(right(#v2,2) as int))/60 as varchar)
+':'+cast(( cast(right(#v1,2) as int) + cast(right(#v2,2) as int))%60 as varchar)