Query to group data by 5 second time intervals - sql

I have a table that has events that occur over a period of 1 hour.
2014-04-16 13:56:06.971 , 3474
2014-04-16 13:56:07.061 , 3609
2014-04-16 13:56:07.067 , 3617
The Table has the Time stamp and event ID
I am trying to group the data to have a count of the number of events that occurred with 5 second intervals, so it looks like this:
0-5 sec., 3
5-10 sec. , 6
10-15 sec. , 4
Thanks in Advance!
I am using SQL Server 2008

You can use a query like that:
declare #Hour datetime = '2014-04-16 13:00:00' -- starting time
select
CONVERT(VARCHAR(10), (DATEDIFF(second, #Hour, EventDateTime) / 5) * 5)
+ '-' + CONVERT(VARCHAR(10), (DATEDIFF(second, #Hour, EventDateTime) / 5 + 1) * 5) + ' sec',
COUNT(EventId)
from intervals
group by DATEDIFF(second, #Hour, EventDateTime) / 5

How about something like this, where you group by the seconds / 12
select
convert(varchar(5),[time stamp],108) as [hh:mm],
cast(min(datepart(s, [time stamp])) as varchar(10)) + ' - ' + cast(max(datepart(s, [time stamp])) as varchar(10)) as [second interval],
count(*) as total
from yourtable
group by convert(varchar(5),[time stamp],108), (datepart(s, [time stamp]) / 12)
or you could create a tally table with the start/end seconds and then join to it.

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;

SUM of a group of time differences in T-SQL?

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

SQL View Query need time interval calculation between 2 dates

I have below View Query. While calculating time interval it only display time interval if check Out is for same date. For example if i check in on 11/12/2017 then it i have to check out with same date 11/12/201 n order to calculate time Interval.
But i want to modify it like if i checkout on next day (after 12:00 AM midnight) it should also calculate the time interval.can some help me to modify query to get the desired results?
Query:
ALTER VIEW [dbo].[TimeAttendanceQuery]
AS
SELECT TOP (100) PERCENT
dbo.AxPerson.Name,
dbo.AxPerson.IdNumber AS EmployeeID,
dbo.TimeAttendance.Badge,
dbo.AxPerson.Id,
MIN(dbo.TimeAttendance.EventTime) AS EntryTime,
MAX(dbo.TimeAttendance.EventTime) AS ExitTime,
CAST(DATEDIFF(second, MIN(dbo.TimeAttendance.EventTime), MAX(dbo.TimeAttendance.EventTime)) / 60 / 60 / 24 AS NVARCHAR(50)) +
':' + CAST(DATEDIFF(second, MIN(dbo.TimeAttendance.EventTime), MAX(dbo.TimeAttendance.EventTime)) / 60 / 60 % 24 AS NVARCHAR(50)) + ':' + CAST(DATEDIFF(second, MIN(dbo.TimeAttendance.EventTime), MAX(dbo.TimeAttendance.EventTime)) / 60 % 60 AS NVARCHAR(50))
AS TimeInterval,
dbo.TimeAttendance.Event,
dbo.AxPerson.Type AS ShitType,
dbo.AxPerson.ShiftDesc,
CONVERT(Varchar,dbo.TimeAttendance.EventTime, 101) AS EventTIME
FROM
dbo.AxPerson
INNER JOIN dbo.TimeAttendance ON dbo.AxPerson.Name = dbo.TimeAttendance.Name
GROUP BY dbo.AxPerson.Name, dbo.AxPerson.IdNumber, dbo.TimeAttendance.Badge, CONVERT(Varchar, dbo.TimeAttendance.EventTime, 101), dbo. AxPerson.ShiftDesc, dbo.AxPerson.Id, dbo.TimeAttendance.Event,dbo.AxPerson.Type
ORDER BY dbo.AxPerson.Name, EventTime DESC
GO
I'm not sure about the algorithm you posted, but if you want to get the time difference from two datetimes you can cast the subtraction as time. This works for less than 24 hours. If you also want the number of days (I think this is only good for less than a year), then you can do the datepart-day of the difference.
For example:
DECLARE #starttime datetime = '2017-11-12 010:20:00'
DECLARE #endtime datetime = '2017-11-13 08:00:00'
SELECT DATEPART(DAY, #endtime - #starttime) - 1 [Days Passed]
,CAST(#endtime - #starttime as time(0)) [Time Passed]
--WHERE the (0) in time(0) is for the milliseconds to return.
Gives output:
Days Passed Time Passed
0 21:40:00
If you don't care about the days, then your code could be modified like this:
ALTER VIEW [dbo].[TimeAttendanceQuery]
AS
SELECT Name, EmployeeID, Badge, Id, EntryTime,
CAST(ExitTime - EntryTime as time(0)) [TimeInterval],
Event, ShiftType, ShiftDesc
,CONVERT(Varchar, EventTime, 101) AS EventTIME
FROM (
SELECT
dbo.AxPerson.Name,
dbo.AxPerson.IdNumber AS EmployeeID,
dbo.TimeAttendance.Badge,
dbo.AxPerson.Id,
MIN(dbo.TimeAttendance.EventTime) AS EntryTime,
MAX(dbo.TimeAttendance.EventTime) AS ExitTime,
dbo.TimeAttendance.Event,
dbo.AxPerson.Type AS ShiftType,
dbo.AxPerson.ShiftDesc,
dbo.TimeAttendance.EventTime
FROM dbo.AxPerson INNER JOIN dbo.TimeAttendance
ON dbo.AxPerson.Name = dbo.TimeAttendance.Name
GROUP BY
dbo.AxPerson.Name,
dbo.AxPerson.IdNumber,
dbo.TimeAttendance.Badge,
dbo.AxPerson.Id,
dbo.TimeAttendance.Event,
dbo.AxPerson.Type
dbo.AxPerson.ShiftDesc,
dbo.TimeAttendance.EventTime,
) AS dT

Calculation more than 24 hours in SQL Server 2008

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

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;