'T-SQL check if event has occurred continuously for 4 hours or more within 24 hours
I have a table (event_tbl) of events that occurred. I need to find out for example if any of the events (Sales, Regcustomer and Transfer) happen continuously for 4 hours with 24 hours.
event_tbl:
| empID | staffID | chartTime | Sales | RegCustomer | Transfer |
|---|---|---|---|---|---|
| T7458529 | 31509 | 2022-04-07 13:20:00.000 | Yes | Yes | Yes |
| T7458529 | 31509 | 2022-04-07 14:00:00.000 | Yes | Yes | Yes |
| T7458529 | 31509 | 2022-04-07 15:00:00.000 | Yes | Yes | No |
| T7458529 | 31509 | 2022-04-07 16:00:00.000 | Yes | Yes | Yes |
| T7458529 | 31509 | 2022-04-07 17:00:00.000 | Yes | No | Yes |
| T7458529 | 31509 | 2022-04-07 18:00:00.000 | Yes | Yes | Yes |
| T7458529 | 31509 | 2022-04-07 19:00:00.000 | Yes | Yes | Yes |
This is my desired result:
| empID | staffID | chartTime | Sales | RegCustomer | Transfer |
|---|---|---|---|---|---|
| T7458529 | 31509 | 2022-04-07 | Yes | Yes | No |
So in this example, events Sales and RegCustomer got flagged as yes because they occurred 4 consecutive times within 24 hours. The Transfer event did not.
Don't even know where to begin as it seems to be complex due to how the events are being logged. Grateful if anyone could help.
Solution 1:[1]
Had to make a few assumptions, but I think this should get you close. Also not sure your expected results are correct. The Transfer event occurs 4 consecutive hours at hours 16-19
Track if Event Occurred 4 Consecutive Hours in a Single Day
DROP TABLE IF EXISTS #Event
DROP Table IF EXISTS #RollingWindowCheck
CREATE TABLE #Event (ID INT IDENTITY(1,1),empID CHAR(8),staffID INT,chartTime DATETIME,Sales CHAR(3),RegCustomer CHAR(3),[Transfer] CHAR(3))
INSERT INTO #Event VALUES
('T7458529',31509,'2022-04-07 13:20:00.000','Yes','Yes','Yes')
,('T7458529',31509,'2022-04-07 14:00:00.000','Yes','Yes','Yes')
,('T7458529',31509,'2022-04-07 15:00:00.000','Yes','Yes','No')
,('T7458529',31509,'2022-04-07 16:00:00.000','Yes','Yes','Yes')
,('T7458529',31509,'2022-04-07 17:00:00.000','Yes','No' ,'Yes')
,('T7458529',31509,'2022-04-07 18:00:00.000','Yes','Yes','Yes')
,('T7458529',31509,'2022-04-07 19:00:00.000','Yes','Yes','Yes');
WITH cte_EventDate AS (
SELECT *,ChartDay = CAST(ChartTime AS DATE)
FROM #Event
)
SELECT *
INTO #RollingWindowCheck
FROM cte_EventDate AS A
OUTER APPLY (
/*Count distinct hours, since where clause limits it to 4 hours, if 4 distinct hours, then you know they are consecutive.
Each column only counts that hour though if the Event = 'Yes'*/
SELECT SalesDistinctHrCnt = COUNT(DISTINCT CASE WHEN Sales = 'Yes' THEN DATEPART(HOUR,DTA.ChartTime) END)
,RegCustomerDistinctHrCnt = COUNT(DISTINCT CASE WHEN RegCustomer = 'Yes' THEN DATEPART(HOUR,DTA.ChartTime) END)
,TransferDistinctHrCnt = COUNT(DISTINCT CASE WHEN [Transfer] = 'Yes' THEN DATEPART(HOUR,DTA.ChartTime) END)
FROM cte_EventDate AS DTA
WHERE A.empID = DTA.empID
AND A.ChartDay = DTA.ChartDay /*Only match to same day*/
AND A.ChartTime BETWEEN DATEADD(HOUR,-4,DTA.ChartTime) AND DTA.ChartTime /*Match to any times within 4 hours*/
AND A.ID <> DTA.ID /*Don't match record to itself. Assuming you have a primary key like ID. Alternatively could use A.ChartTime <> DTA.ChartTime but not ideal*/
) AS B
SELECT
empID
,staffID
,ChartDay
/*Basically if there is a group of 4, you know there were 4 consecutive hours where that event occurred.
If not, will be NULL so use ISNULL to return 'No'*/
,Sales = ISNULL(MAX(CASE WHEN SalesDistinctHrCnt = 4 THEN 'Yes' END),'No')
,RegCustomer = ISNULL(MAX(CASE WHEN RegCustomerDistinctHrCnt = 4 THEN 'Yes' END),'No')
,[Transfer] = ISNULL(MAX(CASE WHEN TransferDistinctHrCnt = 4 THEN 'Yes' END),'No')
FROM #RollingWindowCheck
GROUP BY empID,staffID,ChartDay
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Stephan |
