Related
I have table name tblAttend in which one column named WorkHrs is of datatype varchar.
The result of simple select query is
I sum this column's value and get result in seconds my query is
select sum(DATEDIFF(SECOND, '0:00:00', WorkHrs ))
from tblAttend
and it shows this output:
Now the issue is, when sum of WorkHrs is greater than 24 hours it will throw an error:
What can you suggest to get around this problem? Thanks in advance
Try splitting each time into its component parts by converting the time to a string and then multiplying by the number of seconds relevant to each part.
Data conversion to integer is implicit
select Sum(Left(WorkHrs,2) * 3600 + substring(WorkHrs, 4,2) * 60 + substring(WorkHrs, 7,2))
from tblAttend
Try:
DECLARE #DURATION TIME = '01:43:24'
SELECT DATEDIFF(SECOND, '1/1/1900', CONVERT(DATETIME, #DURATION))
Try this:
SELECT DATEDIFF(SECOND, CONVERT(DATE,GETDATE()), GETDATE())
I have implemented the following function to use it in the management of my projects :
/****** Object: UserDefinedFunction [dbo].[Seconds] Script Date: 10/6/2017 12:00:22 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
/*
select [dbo].[Seconds]('24:00:00'),(24*3600)
select [dbo].[Seconds]('102:56:08'),(102*3600+56*60+8)
*/
ALTER FUNCTION [dbo].[Seconds] (#Time as varchar(50))
RETURNS int
BEGIN
declare #S int, #H int
set #H=cast(SUBSTRING(#Time,1,CHARINDEX(':',#Time)-1) as int)
IF #H<24
set #S=DATEDIFF(SECOND, '0:00:00', #Time)
ELSE BEGIN
set #H=#H-23
set #Time = '23'+SUBSTRING(#Time,CHARINDEX(':',#Time),LEN(#Time)-2)
set #S = (#H*3600)+DATEDIFF(SECOND, '0:00:00', #Time)
END
RETURN #S
END
You may try like this:
SELECT Sec=SUM((DATEPART(HOUR,column name)*3600)+(DATEPART(MINUTE,column name)*60)+(DATEPART(Second,column name)))
FROM [TableName]
You need to convert your WorkHrs to DATETIME first, then perform the DATEDIFF:
WITH Cte(WorkHrs) AS(
SELECT CAST('02:29:11' AS VARCHAR(10)) UNION ALL
SELECT CAST('21:00:00' AS VARCHAR(10)) UNION ALL
SELECT CAST('25:20:02' AS VARCHAR(10))
),
CteConvert(dt) AS(
SELECT
DATEADD(
SECOND,
CAST(SUBSTRING(WorkHrs, 7, 2) AS INT),
DATEADD(
MINUTE,
CAST(SUBSTRING(WorkHrs, 4, 2) AS INT),
DATEADD(
HOUR,
CAST(SUBSTRING(WorkHrs,1, 2) AS INT),
0
)
)
)
FROM Cte
)
SELECT
SUM(DATEDIFF(SECOND, 0, dt)),
-- Formatted to hh:mm:sss
RIGHT('0' + RTRIM(CONVERT(CHAR(2), SUM(DATEDIFF(SECOND, 0, dt)) / (60 * 60))), 2) + ':' +
RIGHT('0' + RTRIM(CONVERT(CHAR(2), (SUM(DATEDIFF(SECOND, 0, dt)) / 60) % 60)), 2) + ':' +
RIGHT('0' + RTRIM(CONVERT(CHAR(2), SUM(DATEDIFF(SECOND, 0, dt)) % 60)),2)
FROM CteConvert
;with cte as (
select
total =Sum(Left(WorkHrs,2) * 3600 + substring(WorkHrs, 4,2) * 60 + substring(WorkHrs, 7,2))
from tblAttend
)
select
total [Total Time in Seconds],
(total / 3600) [Total Time Hour Part],
((total % 3600) / 60) [Total Time Minute Part],
(total % 60) [Total Time Second Part]
from cte
I think you can isolate each part of the time (hour, minute and second) and than sum what you need, please take a look:
declare #tbl table(WorkHrs VARCHAR(8))
insert into #tbl(WorkHrs) values ('02:29:11')
insert into #tbl(WorkHrs) values ('25:00:11')
-- Sum in minutes
SELECT TRY_CAST(([HOURS] * 60) + [MINUTES] + ([SECOND] / 60) AS INT) as TotalInMinutes
FROM (
SELECT
-- Use this aproach to get separated values
SUBSTRING(WorkHrs,1,CHARINDEX(':',WorkHrs)-1) AS [HOURS],
SUBSTRING(WorkHrs,4,CHARINDEX(':',WorkHrs)-1) AS [MINUTES],
SUBSTRING(WorkHrs,7,CHARINDEX(':',WorkHrs)-1) AS [SECOND] -- probably you can ignore this one
FROM #tbl
)
tbl
-- Or try to sum in seconds
SELECT TRY_CAST(([HOURS] * 3600) + ([MINUTES] * 60) + [SECOND] AS INT) as TotalInSeconds
FROM (
SELECT
-- Use this aproach to get separated values
SUBSTRING(WorkHrs,1,CHARINDEX(':',WorkHrs)-1) AS [HOURS],
SUBSTRING(WorkHrs,4,CHARINDEX(':',WorkHrs)-1) AS [MINUTES],
SUBSTRING(WorkHrs,7,CHARINDEX(':',WorkHrs)-1) AS [SECOND]
FROM #tbl
)
tbl
It will return like this to you:
I hope it can help
You can simply use the TIME_TO_SEC function:
SELECT TIME_TO_SEC(WorkHrs) FROM tblAttend;
I need convert a millisecond value, 85605304.3587 to a value like 0d 18h 21m.
No idea on how to start that, is there something similar to a TimeSpan in SQL like there is in C#?
You can do the calculation explicitly. I think it is:
select floor(msvalue / (1000 * 60 * 60 * 24)) as days,
floor(msvalue / (1000 * 60 * 60)) % 24 as hours,
floor(msvalue / (1000 * 60)) % 60 as minutes
Note: Some databases use mod instead of %.
In MS SQL SERVER you can use next code:
with cte as (
select cast(85605304.3587 as int) / 1000 / 60 as [min]
), cte2 as (
select
cast([min] % 60 as varchar(max)) as minutes,
cast(([min] / 60) % 24 as varchar(max)) as hours,
cast([min] / (60 * 24) as varchar(max)) as days
from cte
)
select concat(days, 'd ', hours, 'h ', minutes, 'm') as tm
from cte2
Using native date & time functions, maybe:
SELECT
AsDateTime = DATEADD(MILLISECOND, 85605304, 0)
, AsDateTime2 = DATEADD(NANOSECOND, 7 * 100, DATEADD(MICROSECOND, 358, DATEADD(MILLISECOND, 85605304, CONVERT(datetime2, CONVERT(datetime, 0)))))
-- Incorrect datetime2 approach I initially did, has some precision loss, probably due to datetime's millisecond issue with 0's, 3's, and 7.'s
--SELECT DontDoThis = DATEADD(NANOSECOND, 7 * 100, DATEADD(MICROSECOND, 358, CONVERT(datetime2, DATEADD(MILLISECOND, 85605304, 0))))
datetime covers only 3 digits beyond seconds, while datetime2 will maintain 7 digits. Perhaps other ways that give date-like objects exist, I wouldn't know.
I have table name tblAttend in which one column named WorkHrs is of datatype varchar.
The result of simple select query is
I sum this column's value and get result in seconds my query is
select sum(DATEDIFF(SECOND, '0:00:00', WorkHrs ))
from tblAttend
and it shows this output:
Now the issue is, when sum of WorkHrs is greater than 24 hours it will throw an error:
What can you suggest to get around this problem? Thanks in advance
Try splitting each time into its component parts by converting the time to a string and then multiplying by the number of seconds relevant to each part.
Data conversion to integer is implicit
select Sum(Left(WorkHrs,2) * 3600 + substring(WorkHrs, 4,2) * 60 + substring(WorkHrs, 7,2))
from tblAttend
Try:
DECLARE #DURATION TIME = '01:43:24'
SELECT DATEDIFF(SECOND, '1/1/1900', CONVERT(DATETIME, #DURATION))
Try this:
SELECT DATEDIFF(SECOND, CONVERT(DATE,GETDATE()), GETDATE())
I have implemented the following function to use it in the management of my projects :
/****** Object: UserDefinedFunction [dbo].[Seconds] Script Date: 10/6/2017 12:00:22 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
/*
select [dbo].[Seconds]('24:00:00'),(24*3600)
select [dbo].[Seconds]('102:56:08'),(102*3600+56*60+8)
*/
ALTER FUNCTION [dbo].[Seconds] (#Time as varchar(50))
RETURNS int
BEGIN
declare #S int, #H int
set #H=cast(SUBSTRING(#Time,1,CHARINDEX(':',#Time)-1) as int)
IF #H<24
set #S=DATEDIFF(SECOND, '0:00:00', #Time)
ELSE BEGIN
set #H=#H-23
set #Time = '23'+SUBSTRING(#Time,CHARINDEX(':',#Time),LEN(#Time)-2)
set #S = (#H*3600)+DATEDIFF(SECOND, '0:00:00', #Time)
END
RETURN #S
END
You may try like this:
SELECT Sec=SUM((DATEPART(HOUR,column name)*3600)+(DATEPART(MINUTE,column name)*60)+(DATEPART(Second,column name)))
FROM [TableName]
You need to convert your WorkHrs to DATETIME first, then perform the DATEDIFF:
WITH Cte(WorkHrs) AS(
SELECT CAST('02:29:11' AS VARCHAR(10)) UNION ALL
SELECT CAST('21:00:00' AS VARCHAR(10)) UNION ALL
SELECT CAST('25:20:02' AS VARCHAR(10))
),
CteConvert(dt) AS(
SELECT
DATEADD(
SECOND,
CAST(SUBSTRING(WorkHrs, 7, 2) AS INT),
DATEADD(
MINUTE,
CAST(SUBSTRING(WorkHrs, 4, 2) AS INT),
DATEADD(
HOUR,
CAST(SUBSTRING(WorkHrs,1, 2) AS INT),
0
)
)
)
FROM Cte
)
SELECT
SUM(DATEDIFF(SECOND, 0, dt)),
-- Formatted to hh:mm:sss
RIGHT('0' + RTRIM(CONVERT(CHAR(2), SUM(DATEDIFF(SECOND, 0, dt)) / (60 * 60))), 2) + ':' +
RIGHT('0' + RTRIM(CONVERT(CHAR(2), (SUM(DATEDIFF(SECOND, 0, dt)) / 60) % 60)), 2) + ':' +
RIGHT('0' + RTRIM(CONVERT(CHAR(2), SUM(DATEDIFF(SECOND, 0, dt)) % 60)),2)
FROM CteConvert
;with cte as (
select
total =Sum(Left(WorkHrs,2) * 3600 + substring(WorkHrs, 4,2) * 60 + substring(WorkHrs, 7,2))
from tblAttend
)
select
total [Total Time in Seconds],
(total / 3600) [Total Time Hour Part],
((total % 3600) / 60) [Total Time Minute Part],
(total % 60) [Total Time Second Part]
from cte
I think you can isolate each part of the time (hour, minute and second) and than sum what you need, please take a look:
declare #tbl table(WorkHrs VARCHAR(8))
insert into #tbl(WorkHrs) values ('02:29:11')
insert into #tbl(WorkHrs) values ('25:00:11')
-- Sum in minutes
SELECT TRY_CAST(([HOURS] * 60) + [MINUTES] + ([SECOND] / 60) AS INT) as TotalInMinutes
FROM (
SELECT
-- Use this aproach to get separated values
SUBSTRING(WorkHrs,1,CHARINDEX(':',WorkHrs)-1) AS [HOURS],
SUBSTRING(WorkHrs,4,CHARINDEX(':',WorkHrs)-1) AS [MINUTES],
SUBSTRING(WorkHrs,7,CHARINDEX(':',WorkHrs)-1) AS [SECOND] -- probably you can ignore this one
FROM #tbl
)
tbl
-- Or try to sum in seconds
SELECT TRY_CAST(([HOURS] * 3600) + ([MINUTES] * 60) + [SECOND] AS INT) as TotalInSeconds
FROM (
SELECT
-- Use this aproach to get separated values
SUBSTRING(WorkHrs,1,CHARINDEX(':',WorkHrs)-1) AS [HOURS],
SUBSTRING(WorkHrs,4,CHARINDEX(':',WorkHrs)-1) AS [MINUTES],
SUBSTRING(WorkHrs,7,CHARINDEX(':',WorkHrs)-1) AS [SECOND]
FROM #tbl
)
tbl
It will return like this to you:
I hope it can help
You can simply use the TIME_TO_SEC function:
SELECT TIME_TO_SEC(WorkHrs) FROM tblAttend;
I have the below query which errors out as Operand type clash: time is incompatible with float
select (sum(ReceivedContacts) * CONVERT(TIME, DATEADD(s, SUM(( DATEPART(hh, AverageWaitTime) * 3600 ) + ( DATEPART(mi, AverageWaitTime) * 60 ) + DATEPART(ss, AverageWaitTime)), 0)) / Sum(ReceivedContacts)) AS total_time
from TelephonyStats
Data Type for Received Contacts is float and AverageWaitTime is time
Please help
Remove your CONVERT to TIME and tidy up the rest of parentheses and it should work. Try the below query:
SELECT
SUM(ReceivedContacts) * (
SUM (
( DATEPART(hh, AverageWaitTime) * 3600 ) +
( DATEPART(mi, AverageWaitTime) * 60 ) +
( DATEPART(ss, AverageWaitTime) )
) / SUM(ReceivedContacts)
) AS total_time
FROM TelephonyStats
I have a table like this...
create table test
(
dt datetime
)
In that table the datetime are as follows,
2011/02/02 12:55:00
2011/03/05 00:40:00
2011/02/03 00:12:00
I want to calculate sum hours,mi,ss
In a single Select query not sp.
If any one know please tell me.
Thanks ...
You could sum the times as seconds, then convert to hours, minutes and seconds:
select TotalSeconds / 3600 as [Hours], (TotalSeconds % 3600) / 60 as [Minutes], (TotalSeconds % 3600) % 60 as [Seconds]
from
(
select sum(datepart(hour, dt) * 3600) + sum(datepart(minute, dt) * 60) + sum(datepart(second, dt)) as TotalSeconds
from test
) t
Assuming the sum won't be more than 999 hours:
DECLARE #t TABLE(dt DATETIME);
INSERT #t SELECT '20110202 12:55'
UNION SELECT '20110305 00:40'
UNION SELECT '20110203 00:12';
WITH s AS
(
SELECT s = SUM(DATEDIFF(SECOND,
DATEADD(DAY, 0, DATEDIFF(DAY, 0, dt)), dt))
FROM #t
)
SELECT
s,
hhmmss = RIGHT('000' + RTRIM(s/3600), 3)
+ ':' + RIGHT('00' + RTRIM((s % 3600) / 60), 2)
+ ':' + RIGHT('00' + RTRIM((s % 3600) % 60), 2)
FROM s;
However, if what you are really storing is duration, why not store the number of seconds instead of wedging your data into an inappropriate data type that requires all kinds of workarounds to process properly?
Declare #Table Table
(
DateTimeCol DateTime
)
insert into #Table values ( '2011/02/02 12:55:00')
insert into #Table values ('2011/03/05 00:40:00')
insert into #Table values ('2011/02/03 00:12:00')
;with CTE As
(
--first of all find total seconds of datecolumn
--sum all seconds
Select SUM(
(datepart(hour,DateTimeCol)*60*60)+(datepart(minute,DateTimeCol)*60)+(datepart(second,DateTimeCol))
) As TotalSecond
From #Table
)
--devides with 3600 to get the total hours and then to 60 to get total minutes
Select CONVERT(VARCHAR(10),TotalSecond/3600)+ '.' +
CONVERT(VARCHAR(20),TotalSecond%3600/60) + '.' +
CONVERT(VARCHAR(20),TotalSecond%3600%60) AS [Time] --Total of Time
From CTE