简体   繁体   中英

Hourly Grouping needs to add with previous hour data and subtract with another field in SQL Server

I have to show the count of total Login and Logout of contact center agents in 1 hour bases using SQL Server query.

I have developed the query up to fetching Login and Logout count for every hour of a Day. but I need a field that will show the

SUM(All the Login Count) - SUM(All the Logout Out) 

of previous Intervals and need to show in next interval as Hour wise Login or we shall add the previous Hour wise login data with current interval's login count and subtract interval's current logout count.

Expected data:

在此处输入图像描述

Actual data as of now:

在此处输入图像描述

I used LAG function as well but not getting desired output. Can you please correct me where I'm making mistake in the below query?

Let me know if any create statement is required.

My query:

Declare @FromDate datetime
Declare @ToDate datetime
Declare @AgentID varchar(max);


set @FromDate='2020-05-22 00:00:00'; 
set @ToDate='2020-05-22 23:59:59'; 


;with 

LoginCount AS (
SELECT 
CONVERT(Date,A1.DateTime) AS Date,
    case DATEPART(HOUR,A1.DateTime)
        when 0 then '00:00-00:59' when 1 then '01:00-01:59' when 2 then '02:00-02:59' when 3 then '03:00-03:59' when 4 then '04:00-04:59' when 5 then '05:00-05:59' when 6 then '06:00-06:59' when 7 then '07:00-07:59'
        when 8 then '08:00-08:59' when 9 then '09:00-09:59' when 10 then '10:00-10:59' when 11 then '11:00-11:59' when 12 then '12:00-12:59' when 13 then '13:00-13:59' when 14 then '14:00-14:59' when 15 then '15:00-15:59'
        when 16 then '16:00-16:59' when 17 then '17:00-17:59' when 18 then '18:00-18:59' when 19 then '19:00-19:59' when 20 then '20:00-20:59' when 21 then '21:00-21:59' when 22 then '22:00-22:59' when 23 then '23:00-23:59'
    end AS INTERVAL,
    COUNT(Event) LoginCount
    FROM Agent_Event_Detail A1
    WHERE LoginDateTime BETWEEN @FromDate and @ToDate 
    AND A1.Event=1

GROUP BY CONVERT(Date,A1.DateTime), case DATEPART(HOUR,A1.DateTime)
        when 0 then '00:00-00:59' when 1 then '01:00-01:59' when 2 then '02:00-02:59' when 3 then '03:00-03:59' when 4 then '04:00-04:59' when 5 then '05:00-05:59' when 6 then '06:00-06:59' when 7 then '07:00-07:59'
        when 8 then '08:00-08:59' when 9 then '09:00-09:59' when 10 then '10:00-10:59' when 11 then '11:00-11:59' when 12 then '12:00-12:59' when 13 then '13:00-13:59' when 14 then '14:00-14:59' when 15 then '15:00-15:59'
        when 16 then '16:00-16:59' when 17 then '17:00-17:59' when 18 then '18:00-18:59' when 19 then '19:00-19:59' when 20 then '20:00-20:59' when 21 then '21:00-21:59' when 22 then '22:00-22:59' when 23 then '23:00-23:59'
    end 
)
--select * from LoginCount Order by INTERVAL

,LogoutCount AS (
SELECT 
CONVERT(Date,A1.DateTime) AS Date,
    case DATEPART(HOUR,A1.DateTime)
        when 0 then '00:00-00:59' when 1 then '01:00-01:59' when 2 then '02:00-02:59' when 3 then '03:00-03:59' when 4 then '04:00-04:59' when 5 then '05:00-05:59' when 6 then '06:00-06:59' when 7 then '07:00-07:59'
        when 8 then '08:00-08:59' when 9 then '09:00-09:59' when 10 then '10:00-10:59' when 11 then '11:00-11:59' when 12 then '12:00-12:59' when 13 then '13:00-13:59' when 14 then '14:00-14:59' when 15 then '15:00-15:59'
        when 16 then '16:00-16:59' when 17 then '17:00-17:59' when 18 then '18:00-18:59' when 19 then '19:00-19:59' when 20 then '20:00-20:59' when 21 then '21:00-21:59' when 22 then '22:00-22:59' when 23 then '23:00-23:59'
    end AS INTERVAL,
    COUNT(Event) LogoutCount
    FROM Agent_Event_Detail A1
    WHERE LoginDateTime BETWEEN @FromDate and @ToDate 
    AND A1.Event=2

GROUP BY CONVERT(Date,A1.DateTime), case DATEPART(HOUR,A1.DateTime)
        when 0 then '00:00-00:59' when 1 then '01:00-01:59' when 2 then '02:00-02:59' when 3 then '03:00-03:59' when 4 then '04:00-04:59' when 5 then '05:00-05:59' when 6 then '06:00-06:59' when 7 then '07:00-07:59'
        when 8 then '08:00-08:59' when 9 then '09:00-09:59' when 10 then '10:00-10:59' when 11 then '11:00-11:59' when 12 then '12:00-12:59' when 13 then '13:00-13:59' when 14 then '14:00-14:59' when 15 then '15:00-15:59'
        when 16 then '16:00-16:59' when 17 then '17:00-17:59' when 18 then '18:00-18:59' when 19 then '19:00-19:59' when 20 then '20:00-20:59' when 21 then '21:00-21:59' when 22 then '22:00-22:59' when 23 then '23:00-23:59'
    end 
)
,

--select * from LogoutCount Order by INTERVAL

cteRanked AS
(
   SELECT LoginCount, Date,INTERVAL, ROW_NUMBER() OVER(ORDER BY Date,INTERVAL) rownum
   FROM LoginCount
),
cteRanked1 AS
(
   SELECT LogoutCount, Date,INTERVAL, ROW_NUMBER() OVER(ORDER BY Date,INTERVAL) rownum
   FROM LogoutCount
),

HourlyLoginCount AS
(
SELECT ISNULL(c1.Date,c2.Date) LoginDate,ISNULL(c1.INTERVAL,c2.INTERVAL) LoginInterval,c1.LoginCount,
ISNULL(c2.Date,c1.Date)LogoutDate,ISNULL(c2.INTERVAL,c1.INTERVAL)LogoutInterval,c2.LogoutCount,
ISNULL(c1.LoginCount -c2.LogoutCount,0) [LoginDifference]
 from cteRanked c1 FULL JOIN cteRanked1 c2
ON c1.Date=c2.Date and c1.INTERVAL=c2.INTERVAL
)

select LoginDate,LoginInterval,ISNULL(LoginCount,0)LoginCount,ISNULL(LogoutCount,0)LogoutCount,LoginDifference,
(LoginCount)+(LAG(LoginDifference,1,0) OVER (PARTITION BY LoginDate, LoginInterval ORDER BY LoginDate,LoginInterval))-(LogoutCount)[Hourly Login Count] 
from HourlyLoginCount
order by LoginDate,LoginInterval

You can use sum() over()

Example

Declare @YourTable Table ([LoginDate] date,LoginInterval varchar(50),[Login] int,[Logout] int)  Insert Into @YourTable Values 
 ('2020-05-22','00:00-00:59',6,5)
,('2020-05-22','01:00-01:59',1,0)
,('2020-05-22','04:00-04:59',3,0)
,('2020-05-22','05:00-05:59',71,1)
,('2020-05-22','06:00-06:59',112,23)

Select *
      ,Totals  = sum(Login) over (partition by LoginDate order by LoginInterval) 
                -sum(Logout) over (partition by LoginDate order by LoginInterval)
 from @YourTable

Returns

LoginDate   LoginInterval   Login   Logout  Totals
2020-05-22  00:00-00:59     6       5       1
2020-05-22  01:00-01:59     1       0       2
2020-05-22  04:00-04:59     3       0       5
2020-05-22  05:00-05:59     71      1       75
2020-05-22  06:00-06:59     112     23      164

Just a Note: sample data as text is more useful than images

I would suggest:

with slots as (
    select @fromDate dt
    union all select dateadd(hour, 1,  dt) from slots where dt < @toDate
)
select 
    s.dt,
    sum(case when a.event = 1 then 1 else 0 end) loginCount,
    sum(case when a.event = 2 then 1 else 0 end) logoutCount,
    sum(sum(case when a.event = 1 then 1 else -1 end)) over(order by s.dt) hourly_login_count
from slots s
left join agent_event_detail a
    on  a.event in (1, 2) 
    and a.loginDateTime >= s.dt 
    and a.loginDateTime <  dateadd(hour, 1, s.dt)
group by s.dt

The cte generates the list of hourly slots within the boundaries. Then, the outer query brings in the original table with a left join , and does conditional aggregation to count logins and logouts. The additional computation is performed using window functions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM