1

我希望创建一个查询来计算员工在 5 分钟内处于非活动状态的次数。现在,我想到了一个 CASE 语句,它将他们的扫描分解为 12 段(不要介意转换——我们必须将所有需要更改为 4 小时后,因为服务器位于另一个时区(它糟透了)

case 
    when DATEPART(minute, CONVERT(datetime, SWITCHOFFSET(CONVERT(datetimeoffset, th1.ACTIVITY_DATE_TIME), DATENAME(TzOffset, SYSDATETIMEOFFSET())))) between '0' and '4' then 0
    when DATEPART(minute, CONVERT(datetime, SWITCHOFFSET(CONVERT(datetimeoffset, th1.ACTIVITY_DATE_TIME), DATENAME(TzOffset, SYSDATETIMEOFFSET())))) between '5' and '9' then 1
    when DATEPART(minute, CONVERT(datetime, SWITCHOFFSET(CONVERT(datetimeoffset, th1.ACTIVITY_DATE_TIME), DATENAME(TzOffset, SYSDATETIMEOFFSET())))) between '10' and '14' then 2
    when DATEPART(minute, CONVERT(datetime, SWITCHOFFSET(CONVERT(datetimeoffset, th1.ACTIVITY_DATE_TIME), DATENAME(TzOffset, SYSDATETIMEOFFSET())))) between '15' and '19' then 3
    when DATEPART(minute, CONVERT(datetime, SWITCHOFFSET(CONVERT(datetimeoffset, th1.ACTIVITY_DATE_TIME), DATENAME(TzOffset, SYSDATETIMEOFFSET())))) between '20' and '24' then 4
    when DATEPART(minute, CONVERT(datetime, SWITCHOFFSET(CONVERT(datetimeoffset, th1.ACTIVITY_DATE_TIME), DATENAME(TzOffset, SYSDATETIMEOFFSET())))) between '25' and '29' then 5
    when DATEPART(minute, CONVERT(datetime, SWITCHOFFSET(CONVERT(datetimeoffset, th1.ACTIVITY_DATE_TIME), DATENAME(TzOffset, SYSDATETIMEOFFSET())))) between '30' and '34' then 6
    when DATEPART(minute, CONVERT(datetime, SWITCHOFFSET(CONVERT(datetimeoffset, th1.ACTIVITY_DATE_TIME), DATENAME(TzOffset, SYSDATETIMEOFFSET())))) between '35' and '39' then 7
    when DATEPART(minute, CONVERT(datetime, SWITCHOFFSET(CONVERT(datetimeoffset, th1.ACTIVITY_DATE_TIME), DATENAME(TzOffset, SYSDATETIMEOFFSET())))) between '40' and '44' then 8
    when DATEPART(minute, CONVERT(datetime, SWITCHOFFSET(CONVERT(datetimeoffset, th1.ACTIVITY_DATE_TIME), DATENAME(TzOffset, SYSDATETIMEOFFSET())))) between '45' and '49' then 9
    when DATEPART(minute, CONVERT(datetime, SWITCHOFFSET(CONVERT(datetimeoffset, th1.ACTIVITY_DATE_TIME), DATENAME(TzOffset, SYSDATETIMEOFFSET())))) between '50' and '54' then 10
    when DATEPART(minute, CONVERT(datetime, SWITCHOFFSET(CONVERT(datetimeoffset, th1.ACTIVITY_DATE_TIME), DATENAME(TzOffset, SYSDATETIMEOFFSET())))) between '55' and '59' then 11
    END)) 

然后我取出不同数量的数字 0-11 并从 12 中减去它。我知道这不是一个完美的系统,因为如果有人在 7:01 进行扫描,而在 7:09 进行下一次扫描,它不会标记为 5 -分钟间隙。

有谁知道跟踪交易历史差距的更好方法?

4

1 回答 1

0

LAG 分析函数来拯救你。

这是使用此示例数据的简单演示

create table emp_pause 
(emp_no int,
 work_time date);

insert into emp_pause values(1, to_date('01012019 0810','ddmmyyyy hh24mi'));
insert into emp_pause values(1, to_date('01012019 0812','ddmmyyyy hh24mi'));
insert into emp_pause values(1, to_date('01012019 0817','ddmmyyyy hh24mi'));
insert into emp_pause values(1, to_date('01012019 0818','ddmmyyyy hh24mi'));
insert into emp_pause values(1, to_date('01012019 0830','ddmmyyyy hh24mi'));
insert into emp_pause values(2, to_date('01012019 1000','ddmmyyyy hh24mi'));
insert into emp_pause values(2, to_date('01012019 1004','ddmmyyyy hh24mi'));
insert into emp_pause values(2, to_date('01012019 1012','ddmmyyyy hh24mi'));
insert into emp_pause values(2, to_date('01012019 1029','ddmmyyyy hh24mi'));
insert into emp_pause values(2, to_date('01012019 1030','ddmmyyyy hh24mi'));
commit;

此查询计算当前时间戳与同一员工上一行的值的差异(以分钟为单位)。

select emp_no, work_time,
trunc((work_time - lag(work_time) over (partition by emp_no order by work_time)) *24*60) interval_minutes
from emp_pause order by emp_no, work_time;

    EMP_NO WORK_TIME           INTERVAL_MINUTES
---------- ------------------- ----------------
         1 01.01.2019 08:10:00                  
         1 01.01.2019 08:12:00                2 
         1 01.01.2019 08:17:00                5 
         1 01.01.2019 08:18:00                1 
         1 01.01.2019 08:30:00               12 
         2 01.01.2019 10:00:00                  
         2 01.01.2019 10:04:00                4 
         2 01.01.2019 10:12:00                8 
         2 01.01.2019 10:29:00               17 
         2 01.01.2019 10:30:00                1 

仅过滤比请求的 5 分钟长的时间间隔:

with emp as (
select emp_no, work_time,
trunc((work_time - lag(work_time) over (partition by emp_no order by work_time)) *24*60) interval_minutes
from emp_pause)
select * from emp 
where interval_minutes >= 5
order by 1,2;

    EMP_NO WORK_TIME           INTERVAL_MINUTES
---------- ------------------- ----------------
         1 01.01.2019 08:17:00                5 
         1 01.01.2019 08:30:00               12 
         2 01.01.2019 10:12:00                8 
         2 01.01.2019 10:29:00               17
于 2019-10-10T18:08:34.130 回答