I want to sum all the time differences to show the total hours worked.
select
aaaa
from
employee B
inner join
(select
s.emp_reader_id,
Sum(case when s.in_time is not null and s.out_time is not null and s.shift_type_id=5 and LOWER(DATENAME(dw, [att_date]))='friday'then
cast(datediff(minute,'00:00:00', '23:59:59') / 60 +
(datediff(minute,'00:00:00', '23:59:59') % 60 / 100.0) as decimal(7, 4)
) end) as aaaa
from
Daily_attendance_data s
left outer join
employee bb on s.emp_reader_id = bb.emp_reader_id
where
att_date between '2018-10-01' and '2018-10-31'
and s.emp_reader_id = 1039
group by
s.emp_reader_id) A on B.emp_reader_id = A.emp_reader_id
Current output:
aaaa
47.1800
which gives the list of times by hours but then I want to sum it up to a grand total.
It would just total
Sample data :
23:59
23:59
Expected output:
47.58
I think you should convert all times to seconds, calculate the SUM then convert the total to HH:mm:ss.
Calculate The SUM of seconds
DECLARE #TimeinSecond as integer = 0
select #TimeinSecond = Sum(DATEDIFF(SECOND, '0:00:00', [WorkHrs]))
from Daily_attendance_data
Convert the HH:mm:ss Format
SELECT RIGHT('0' + CAST(#TimeinSecond / 3600 AS VARCHAR),2) + ':' +
RIGHT('0' + CAST((#TimeinSecond / 60) % 60 AS VARCHAR),2) + ':' +
RIGHT('0' + CAST(#TimeinSecond % 60 AS VARCHAR),2)
References
How to convert hh:mm:ss to seconds in SQL Server with more than 24 hours
SQL SERVER – Convert Seconds to Hour : Minute : Seconds Format
If your date type is DateTime.
you can try to let your value split two part.
hours get value need to condider carry from minutes so do SUM(intpart) + SUM(floatpart) / 60
minutes get value from SUM(floatpart) % 60
look like this.
SELECT concat(SUM(intpart) + SUM(floatpart) / 60,':', SUM(floatpart) % 60)
FROM (
SELECT cast(SUBSTRING (cast(col as varchar),0,3) as int) intpart,
cast(SUBSTRING (cast(col as varchar),CHARINDEX(':',col) +1,2)as int) floatpart
FROM T
) t1
sqlfiddle
Related
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;
I have the following code which is working, however how do I get the terminal minutes to show the output as Day, Hour, Minute? If this cannot be done, is it possible to add a +1 on the time which would indicate it's the following day?
The problem I am having is that when our orders run past 23.59 PM, the system is not displaying the correct format because of the 24 hour time period.
I am stumped and hope I am not confusing matters.
SELECT FOLIO_NUMBER, TERMINAL_NAME,
format((START_LOAD_TIME - ORDER_ENTRY_TIME), 'HH:mm') AS STAGING_MINUTES,
format((TERM_END_LOAD_TIME - START_LOAD_TIME), 'HH:mm') AS LOADING_MINUTES,
format((TERM_END_LOAD_TIME - ORDER_ENTRY_TIME), 'HH:mm') AS TERMINAL_MINUTES
FROM ORDERS
JOIN TERMINAL_OWNER ON ORDERS.LOADING_TERMINAL_ID = TERMINAL_OWNER.TERMINAL_ID
DECLARE #INT INT
SET #INT = DATEDIFF(SECOND,GETDATE(),GETDATE()+1)
select
convert(varchar(10), (#INT/86400)) + ':' +
convert(varchar(10), ((#INT%86400)/3600)) + ':'+
convert(varchar(10), (((#INT%86400)%3600)/60)) + ':'+
convert(varchar(10), (((#INT%86400)%3600)%60)) as 'DD:HH:MM:SS'
Courtesy of Nat-MS. See here
I think you are looking for something like this
Declare #theMinutes Varchar(10)
Set #theMinutes = '19:25'
declare #totMintute int
Select
#totMintute = (Cast(
Cast(left(#theMinutes,charindex(':',#theMinutes)-1) as Int) * 60
+ Cast(substring(#theMinutes,charindex(',',#theMinutes)+4,len(#theMinutes)) as Int)
as Int ) * 60) / 60
--For 12 hour 1 days
Select #totMintute / 720 as NoDays -- 720 minutes per day
, (#totMintute % 720) / 60 as NoHours -- modulo 720
, (#totMintute % 60) as NoMinutes -- modulo 60
--For 24 hour 1 days
Select #totMintute / 1440 as NoDays -- 1440 minutes per day
, (#totMintute % 1440) / 60 as NoHours -- modulo 1440
, (#totMintute % 60) as NoMinutes -- modulo 60
The output will look like as shown below.
You can convert this query data source table as shown below.
Create table #Temp (MinValue Varchar(8))
insert into #Temp Values ('19:25')
Select TotMinute / 720 as NoDays -- 1440 minutes per day
, (TotMinute % 720) / 60 as NoHours -- modulo 1440
, (TotMinute % 60) as NoMinutes -- modulo 60
from(
select
(Cast(
Cast(left(MinValue,charindex(':',MinValue)-1) as Int) * 60
+ Cast(substring(MinValue,charindex(',',MinValue)+4,len(MinValue)) as Int)
as Int ) * 60) / 60 as TotMinute
from #Temp
)a
You can find the live demo here.
I would say that you should remove the need to identify days/hours in the SQL Output and just get the difference in minutes, which you can then work with in your application layer.
Take this sample code:
create table #orders (
FOLIO_NUMBER int,
START_LOAD_TIME datetime,
ORDER_ENTRY_TIME datetime,
TERM_END_LOAD_TIME datetime
)
insert into #orders (FOLIO_NUMBER,START_LOAD_TIME,ORDER_ENTRY_TIME,TERM_END_LOAD_TIME)
values (1, getdate(),getdate() - 1,getdate() + 1)
select *,
datediff(mi, ORDER_ENTRY_TIME, START_LOAD_TIME) AS STAGING_MINUTES,
datediff(mi, START_LOAD_TIME, TERM_END_LOAD_TIME) AS LOADING_MINUTES,
datediff(mi, ORDER_ENTRY_TIME, TERM_END_LOAD_TIME) AS TERMINAL_MINUTES
from #orders
drop table #orders
This will output the minutes difference between the events:
FOLIO_NUMBER STAGING_MINUTES LOADING_MINUTES TERMINAL_MINUTES
1 1440 1440 2880
You can then perform some simple maths with these values to extract, days, hours and minutes.
I can't seem to find out how to get the total number of hours from varchar column from SQL Server 2016.
Query:
SELECT taakuren
FROM taken
Returns
10:00
12:15
26:00
40:00
I would like it to return
88:15
I've tried things like below query but a always end up with issue when it gets past 24 hours
select Convert(Varchar, (Convert(DateTime, taakuren)), 114) as TotalTime
from taken
Basically, the time data type peters out at 24 hours. If you want more hours, then you may have to resort to your own arithmetic:
select cast(sum(hours * 60 + minutes) / 60 as varchar(10)) + ':' +
right('00' + cast(sum(hours * 60 + minutes) % 60 as varchar(10)))
from taken t outer apply
(values (left(t.taakuren, 2) + 0, right(t.taakuren, 2) + 0)
) v(hours, minutes);
update my code is:
select cast(sum(hours * 60 + minutes) / 60 as varchar(10)) + ':' +
cast(sum(hours * 60 + minutes) % 60 as varchar(10))
from taken t outer apply
(values (left(t.taakuren, 2) + 0, SUBSTRING(t.taakuren, 4,6) + 0)
) v(hours, minutes)
I have multiple records as workinghours of employee as
02:10:00
03:00:00
12:00:00
12:34:56
Now i need to add these record and want to display in
`hh:mm:ss`
Format. I used following query but it only works when sum of record less than 24 hours but record may be greater than 24 hours.
SELECT CAST(DATEADD(MILLISECOND,
SUM(DATEDIFF(MILLISECOND, '00:00:00.000'
, CAST(WorkHrs AS TIME))), '00:00:00.000') AS TIME) AS Total_Time
FROM tblAttend
I spend more than 4 hours on google to find solution but got no success anymore.
Datatype of workinghour column is varchar .
The time data type has an explicit range only up to 24 hours (see here).
So, I think you are basically stuck with doing the conversion yourself. It is ugly, but looks something like:
SELECT RIGHT('00' + CAST(SUM(DATEDIFF(MILLISECOND, '00:00:00.000', CAST(WorkHrs AS TIME))), '00:00:00.000')/(60*60) AS VARCHAR(255)), 2)
) +
RIGHT('00' + CAST((SUM(DATEDIFF(MILLISECOND, '00:00:00.000', CAST(WorkHrs AS TIME))), '00:00:00.000')/60 % 60) AS VARCHAR(255)), 2) +
RIGHT('00' + CAST(SUM(DATEDIFF(MILLISECOND, '00:00:00.000', CAST(WorkHrs AS TIME))), '00:00:00.000') % 60 AS VARCHAR(255)), 2)
)
Merhaba Waqas,
Could you please try following SQL CTE Select statement,
It returns hours value more than 24, for this case it was 29 I guess.
Please check time calculation on SQL Server, this select is adapted from there
;with cte as (
select
userid,
total = sum( DATEPART(ss,period) + 60 * DATEPART(mi,period) + 3600 * DATEPART(hh,period) )
from WorkingHours
group by userid
)
select
userid,
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 hope it helps you
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;