September 4, 2016 at 5:10 am
I am trying to sum up time and almost did it. Now I would like to sum up top 2 time as follows:
SELECT TOP 2*,
ISNULL((RIGHT('00' + CONVERT(VARCHAR(10), SUM(DATEDIFF(MINUTE, FromTime, ToTime)) / 60), 2)
+ ':' +
RIGHT('00' + CONVERT(VARCHAR(2), SUM(DATEDIFF(Minute, FromTime, ToTime)) % 60), 2)
+ ':' +
RIGHT('00' + CONVERT(VARCHAR(2), SUM(DATEDIFF(SECOND, FromTime, ToTime)) % 60), 2)), 0)
AS TotalTime FROM Demo GROUP BY ID, FromTime, ToTime
The output is as follows:
So is there any way or still possible to add the sum of the TotalTime column at the end? I would appreciate if any idea is shared. Thanks.
September 4, 2016 at 6:43 am
Quick thought, the time calculation is not correct, the second result sould be 02:30:21 so there is an extra minute there in the results.
😎
Here are three different methods
USE TEEST;
GO
SET NOCOUNT ON;
;WITH DEMO(ID,FromTime,ToTime) AS
(
SELECT
ID
,CONVERT(DATETIME,FromTime,120) AS FromTime
,CONVERT(DATETIME,ToTime,120) AS ToTime
FROM (VALUES (1,'2016-09-03 18:14:47.000','2016-09-03 20:32:54.000')
,(2,'2016-09-03 12:35:45.000','2016-09-03 15:06:06.000')
) AS X(ID,FromTime,ToTime)
)
SELECT
D.ID
,D.FromTime
,D.ToTime
,CONVERT(TIME(0),D.ToTime - D.FromTime,0) AS TIME_DIFF_01
,DATEADD(SECOND,DATEDIFF(SECOND,D.FromTime,D.ToTime),CONVERT(TIME(0),'00:00:00',0)) AS TIME_DIFF_02
,CONVERT(TIME(0),DATEADD(SECOND,DATEDIFF(SECOND,D.FromTime,D.ToTime),CONVERT(DATETIME,0,0)),0) AS TIME_DIFF_03
,CONVERT(TIME(0),CONVERT(DATETIME,SUM(CONVERT(FLOAT,D.ToTime,0) - CONVERT(FLOAT,D.FromTime,0))OVER
(
PARTITION BY (SELECT NULL)
),0),0) AS TIME_SUM_01
,DATEADD(SECOND,SUM(DATEDIFF(SECOND,D.FromTime,D.ToTime)) OVER
(
PARTITION BY (SELECT NULL)
),CONVERT(TIME(0),'00:00:00',0)) AS TIME_SUM_02
,CONVERT(TIME(0),DATEADD(SECOND,SUM(DATEDIFF(SECOND,D.FromTime,D.ToTime)) OVER
(
PARTITION BY (SELECT NULL)
),CONVERT(DATETIME,0,0)),0) AS TIME_SUM_03
FROM DEMO D;
Output
ID FromTime ToTime TIME_DIFF_01 TIME_DIFF_02 TIME_DIFF_03 TIME_SUM_01 TIME_SUM_02 TIME_SUM_03
----------- ----------------------- ----------------------- ---------------- ---------------- ---------------- ---------------- ---------------- ----------------
1 2016-09-03 18:14:47.000 2016-09-03 20:32:54.000 02:18:07 02:18:07 02:18:07 04:48:28 04:48:28 04:48:28
2 2016-09-03 12:35:45.000 2016-09-03 15:06:06.000 02:30:21 02:30:21 02:30:21 04:48:28 04:48:28 04:48:28
September 4, 2016 at 7:04 am
Thanks a lot. Works perfectly 🙂 🙂
September 4, 2016 at 7:19 am
do you have time differences of greater than 24 hours?
eg
;WITH DEMO(ID,FromTime,ToTime) AS
(
SELECT
ID
,CONVERT(DATETIME,FromTime,120) AS FromTime
,CONVERT(DATETIME,ToTime,120) AS ToTime
FROM (VALUES (1,'2016-09-03 23:59:59.000','2016-09-04 00:00:01.000')
,(2,'2016-09-01 12:35:45.000','2016-09-04 15:06:06.000')
,(3,'2016-09-01 12:35:45.000','2016-09-02 12:35:44.000')
,(4,'2016-09-01 12:35:45.000','2016-09-02 12:35:45.000')
,(5,'2016-09-01 12:35:45.000','2016-09-02 12:35:46.000')
) AS X(ID,FromTime,ToTime)
)
SELECT
D.ID
,D.FromTime
,D.ToTime
,CONVERT(TIME(0),D.ToTime - D.FromTime,0) AS TIME_DIFF_01
,DATEADD(SECOND,DATEDIFF(SECOND,D.FromTime,D.ToTime),CONVERT(TIME(0),'00:00:00',0)) AS TIME_DIFF_02
,CONVERT(TIME(0),DATEADD(SECOND,DATEDIFF(SECOND,D.FromTime,D.ToTime),CONVERT(DATETIME,0,0)),0) AS TIME_DIFF_03
,CONVERT(TIME(0),CONVERT(DATETIME,SUM(CONVERT(FLOAT,D.ToTime,0) - CONVERT(FLOAT,D.FromTime,0))OVER
(
PARTITION BY (SELECT NULL)
),0),0) AS TIME_SUM_01
,DATEADD(SECOND,SUM(DATEDIFF(SECOND,D.FromTime,D.ToTime)) OVER
(
PARTITION BY (SELECT NULL)
),CONVERT(TIME(0),'00:00:00',0)) AS TIME_SUM_02
,CONVERT(TIME(0),DATEADD(SECOND,SUM(DATEDIFF(SECOND,D.FromTime,D.ToTime)) OVER
(
PARTITION BY (SELECT NULL)
),CONVERT(DATETIME,0,0)),0) AS TIME_SUM_03
FROM DEMO D;
________________________________________________________________
you can lead a user to data....but you cannot make them think
and remember....every day is a school day
September 4, 2016 at 7:41 am
J Livingston SQL (9/4/2016)
do you have time differences of greater than 24 hours?
Good point:pinch:, obviously the TIME data type isn't fit for purpose if either a single interval or the sum of intervals exceeds 24 hours.
😎
September 4, 2016 at 8:23 am
This code will return the interval in the format of DD:HH:MM:SS
😎
USE TEEST;
GO
SET NOCOUNT ON;
;WITH DEMO(ID,FromTime,ToTime) AS
(
SELECT
ID
,CONVERT(DATETIME,FromTime,120) AS FromTime
,CONVERT(DATETIME,ToTime,120) AS ToTime
FROM (VALUES (1,'2016-09-03 23:59:59.000','2016-09-04 00:00:01.000')
,(2,'2016-09-01 12:35:45.000','2016-09-04 15:06:06.000')
,(3,'2016-09-01 12:35:45.000','2016-09-02 12:35:44.000')
,(4,'2016-09-01 12:35:45.000','2016-09-02 12:35:45.000')
,(5,'2016-09-01 12:35:45.000','2016-09-02 12:35:46.000')
) AS X(ID,FromTime,ToTime)
)
,BASE_DATA AS
(
SELECT
D.ID
,D.FromTime
,D.ToTime
,DATEDIFF(SECOND,D.FromTime,D.ToTime) AS TIME_DIFF_SECOND
,SUM(DATEDIFF(SECOND,D.FromTime,D.ToTime)) OVER
(
PARTITION BY (SELECT NULL)
) AS TIME_DIFF_SUM
FROM DEMO D
)
SELECT
BD.ID
,BD.FromTime
,BD.ToTime
,CONVERT(VARCHAR(12),DATEDIFF(DAY,0,DATEADD(SECOND,BD.TIME_DIFF_SECOND,0)),0) + CHAR(58)
+ CONVERT(CHAR(8),CONVERT(TIME(0),DATEADD(SECOND,BD.TIME_DIFF_SECOND,0),0),120) AS DDHHMMSS
,CONVERT(VARCHAR(12),DATEDIFF(DAY,0,DATEADD(SECOND,BD.TIME_DIFF_SUM,0)),0) + CHAR(58)
+ CONVERT(CHAR(8),CONVERT(TIME(0),DATEADD(SECOND,BD.TIME_DIFF_SUM,0),0),120) AS SUM_DDHHMMSS
FROM BASE_DATA BD
;
Output
ID FromTime ToTime DDHHMMSS SUM_DDHHMMSS
----------- ----------------------- ----------------------- --------------------- ---------------------
1 2016-09-03 23:59:59.000 2016-09-04 00:00:01.000 0:00:00:02 6:02:30:23
2 2016-09-01 12:35:45.000 2016-09-04 15:06:06.000 3:02:30:21 6:02:30:23
3 2016-09-01 12:35:45.000 2016-09-02 12:35:44.000 0:23:59:59 6:02:30:23
4 2016-09-01 12:35:45.000 2016-09-02 12:35:45.000 1:00:00:00 6:02:30:23
5 2016-09-01 12:35:45.000 2016-09-02 12:35:46.000 1:00:00:01 6:02:30:23
September 4, 2016 at 9:15 am
Thanks all for the answers. Just wondering why the below query didn't work using TOP 2 directly:
SELECT TOP 2
k.ID,
k.FromTime,
k.ToTime,
DATEADD(SECOND,DATEDIFF(SECOND, k.FromTime, k.ToTime),CONVERT(TIME(0),'00:00:00',0)) AS TIME_DIFF,
DATEADD(SECOND,SUM(DATEDIFF(SECOND, k.FromTime, k.ToTime)) OVER
(
PARTITION BY (SELECT NULL)
),CONVERT(TIME(0),'00:00:00',0)) AS TIME_SUM
FROM Demo k;
But in the below case, it almost creates a new table say 'Hello' to select the TOP 2 data or records:
;WITH Hello AS
(
SELECT TOP 1
ID, FromTime, ToTime
FROM Demo
)
SELECT TOP 2
k.ID,
k.FromTime,
k.ToTime,
DATEADD(SECOND,DATEDIFF(SECOND, k.FromTime, k.ToTime),CONVERT(TIME(0),'00:00:00',0)) AS TIME_DIFF,
DATEADD(SECOND,SUM(DATEDIFF(SECOND, k.FromTime, k.ToTime)) OVER
(
PARTITION BY (SELECT NULL)
),CONVERT(TIME(0),'00:00:00',0)) AS TIME_SUM
FROM Hello k;
Is there any reason behind it? Just want to know. Thanks.
September 4, 2016 at 9:29 am
Simply add the grouping as the first CTE
😎
USE TEEST;
GO
SET NOCOUNT ON;
;WITH DEMO(ID,FromTime,ToTime) AS
(
SELECT
ID
,CONVERT(DATETIME,FromTime,120) AS FromTime
,CONVERT(DATETIME,ToTime,120) AS ToTime
FROM (VALUES (1,'2016-09-03 23:59:59.000','2016-09-04 00:00:01.000')
,(2,'2016-09-01 12:35:45.000','2016-09-04 15:06:06.000')
,(3,'2016-09-01 12:35:45.000','2016-09-02 12:35:44.000')
,(4,'2016-09-01 12:35:45.000','2016-09-02 12:35:45.000')
,(5,'2016-09-01 12:35:45.000','2016-09-02 12:35:46.000')
) AS X(ID,FromTime,ToTime)
)
,FIRST_GROUP AS
(
SELECT
TOP(2)
DD.ID
,DD.FromTime
,DD.ToTime
FROM DEMO DD
ORDER BY DATEDIFF(SECOND,DD.FromTime,DD.ToTime) DESC
)
,BASE_DATA AS
(
SELECT
FG.ID
,FG.FromTime
,FG.ToTime
,DATEDIFF(SECOND,FG.FromTime,FG.ToTime) AS TIME_DIFF_SECOND
,SUM(DATEDIFF(SECOND,FG.FromTime,FG.ToTime)) OVER
(
PARTITION BY (SELECT NULL)
) AS TIME_DIFF_SUM
FROM FIRST_GROUP FG
)
SELECT
BD.ID
,BD.FromTime
,BD.ToTime
,CONVERT(VARCHAR(12),DATEDIFF(DAY,0,DATEADD(SECOND,BD.TIME_DIFF_SECOND,0)),0) + CHAR(58)
+ CONVERT(CHAR(8),CONVERT(TIME(0),DATEADD(SECOND,BD.TIME_DIFF_SECOND,0),0),120) AS DDHHMMSS
,CONVERT(VARCHAR(12),DATEDIFF(DAY,0,DATEADD(SECOND,BD.TIME_DIFF_SUM,0)),0) + CHAR(58)
+ CONVERT(CHAR(8),CONVERT(TIME(0),DATEADD(SECOND,BD.TIME_DIFF_SUM,0),0),120) AS SUM_DDHHMMSS
FROM BASE_DATA BD
;
Output
ID FromTime ToTime DDHHMMSS SUM_DDHHMMSS
----------- ----------------------- ----------------------- --------------------- ---------------------
2 2016-09-01 12:35:45.000 2016-09-04 15:06:06.000 3:02:30:21 4:02:30:22
5 2016-09-01 12:35:45.000 2016-09-02 12:35:46.000 1:00:00:01 4:02:30:22
September 4, 2016 at 1:51 pm
Eirikur Eiriksson (9/4/2016)
This code will return the interval in the format of DD:HH:MM:SS😎
USE TEEST;
GO
SET NOCOUNT ON;
;WITH DEMO(ID,FromTime,ToTime) AS
(
SELECT
ID
,CONVERT(DATETIME,FromTime,120) AS FromTime
,CONVERT(DATETIME,ToTime,120) AS ToTime
FROM (VALUES (1,'2016-09-03 23:59:59.000','2016-09-04 00:00:01.000')
,(2,'2016-09-01 12:35:45.000','2016-09-04 15:06:06.000')
,(3,'2016-09-01 12:35:45.000','2016-09-02 12:35:44.000')
,(4,'2016-09-01 12:35:45.000','2016-09-02 12:35:45.000')
,(5,'2016-09-01 12:35:45.000','2016-09-02 12:35:46.000')
) AS X(ID,FromTime,ToTime)
)
,BASE_DATA AS
(
SELECT
D.ID
,D.FromTime
,D.ToTime
,DATEDIFF(SECOND,D.FromTime,D.ToTime) AS TIME_DIFF_SECOND
,SUM(DATEDIFF(SECOND,D.FromTime,D.ToTime)) OVER
(
PARTITION BY (SELECT NULL)
) AS TIME_DIFF_SUM
FROM DEMO D
)
SELECT
BD.ID
,BD.FromTime
,BD.ToTime
,CONVERT(VARCHAR(12),DATEDIFF(DAY,0,DATEADD(SECOND,BD.TIME_DIFF_SECOND,0)),0) + CHAR(58)
+ CONVERT(CHAR(8),CONVERT(TIME(0),DATEADD(SECOND,BD.TIME_DIFF_SECOND,0),0),120) AS DDHHMMSS
,CONVERT(VARCHAR(12),DATEDIFF(DAY,0,DATEADD(SECOND,BD.TIME_DIFF_SUM,0)),0) + CHAR(58)
+ CONVERT(CHAR(8),CONVERT(TIME(0),DATEADD(SECOND,BD.TIME_DIFF_SUM,0),0),120) AS SUM_DDHHMMSS
FROM BASE_DATA BD
;
Output
ID FromTime ToTime DDHHMMSS SUM_DDHHMMSS
----------- ----------------------- ----------------------- --------------------- ---------------------
1 2016-09-03 23:59:59.000 2016-09-04 00:00:01.000 0:00:00:02 6:02:30:23
2 2016-09-01 12:35:45.000 2016-09-04 15:06:06.000 3:02:30:21 6:02:30:23
3 2016-09-01 12:35:45.000 2016-09-02 12:35:44.000 0:23:59:59 6:02:30:23
4 2016-09-01 12:35:45.000 2016-09-02 12:35:45.000 1:00:00:00 6:02:30:23
5 2016-09-01 12:35:45.000 2016-09-02 12:35:46.000 1:00:00:01 6:02:30:23
thanks Eirikur .. seems sound.. a keeper for me.
________________________________________________________________
you can lead a user to data....but you cannot make them think
and remember....every day is a school day
September 4, 2016 at 9:54 pm
There is a much simpler way to find time difference between 2 datetime values:
TimeDifference = TimeTo - TimeFrom
THis will allow to count milliseconds too:
;WITH DEMO(ID,FromTime,ToTime) AS
(
SELECT
ID
,CONVERT(DATETIME,FromTime,120) AS FromTime
,CONVERT(DATETIME,ToTime,120) AS ToTime
FROM (VALUES (1,'2016-09-03 23:59:59.000','2016-09-04 00:00:01.100')
,(2,'2016-09-01 12:35:45.000','2016-09-04 15:06:06.020')
,(3,'2016-09-01 12:35:45.000','2016-09-02 12:35:44.003')
,(4,'2016-09-01 12:35:45.000','2016-09-02 12:35:45.400')
,(5,'2016-09-01 12:35:45.000','2016-09-02 12:35:46.050')
) AS X(ID,FromTime,ToTime)
)
SELECT
DD.ID ,DD.FromTime ,DD.ToTime,
Duration = DD.ToTime - DD.FromTime ,
TotalDuration = CONVERT(DATETIME, TotalDuration) ,
SUM_DDHHMMSS = CONVERT(VARCHAR(10), FLOOR(td.TotalDuration)) + ':'
+ CONVERT(VARCHAR(20), CONVERT(DATETIME, td.TotalDuration), 114)
FROM DEMO DD
CROSS JOIN (
SELECT SUM( CONVERT(FLOAT, ToTime - FromTime)) TotalDuration
FROM DEMO
) td
ORDER BY (ToTime - FromTime) DESC
_____________
Code for TallyGenerator
Viewing 10 posts - 1 through 9 (of 9 total)
You must be logged in to reply to this topic. Login to reply