При почасовой группировке необходимо добавить данные за предыдущий час и вычесть из другого поля в SQL Server. - PullRequest
3 голосов
/ 25 мая 2020

Я должен показать общее количество входов в систему и выходов из системы агентов контакт-центра за 1 час, используя SQL запрос сервера.

Я разработал запрос для получения количества входов и выходов из системы за каждый час дня. но мне нужно поле, которое будет отображать

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

предыдущих интервалов и должно отображаться в следующем интервале как почасовой вход в систему, или мы добавим предыдущие данные почасового входа в систему с текущим счетчиком входа в систему и вычтем интервал текущее количество выходов.

Ожидаемые данные:

enter image description here

Фактические данные на текущий момент:

enter image description here

Я также использовал функцию LAG, но не получил желаемого результата. Не могли бы вы исправить мою ошибку в приведенном ниже запросе?

Сообщите мне, требуется ли какой-либо оператор создания.

Мой запрос:

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

Ответы [ 2 ]

1 голос
/ 25 мая 2020

Я бы посоветовал:

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

cte генерирует список почасовых интервалов в пределах границ. Затем внешний запрос вводит исходную таблицу с left join и выполняет условную агрегацию для подсчета входов в систему и выхода из системы. Дополнительные вычисления выполняются с помощью оконных функций.

1 голос
/ 25 мая 2020

Вы можете использовать sum() over()

Пример

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

Возвращает

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

Просто примечание: образец данных в виде текста более полезен, чем изображения

...