根据开始日期和结束日期列计算并发记录

Counting concurrent records based on startdate and enddate columns

table结构:

人事记录

如何在给定日期和员工所属的组 ID 的情况下获取员工配置记录列表,其中在职员工的数量在一天中的任何时刻都低于阈值,例如 3?

按照我的大脑工作方式,我会在一天中的每一分钟重复调用存储过程,但这当然会非常低效:

SELECT COUNT(PersonnelId) 
FROM DailyRosters 
WHERE GroupId=@GroupId 
    AND StaffingStartTime <= @TimeParam 
    AND StaffingEndTime > @TimeParam 
    AND COUNT(GroupId) < 3
GROUP BY GroupId
HAVING COUNT(PersonnelId) < 3

编辑:如果有助于提炼问题,员工可能会全天来来去去。例如,Personnel 可能有 0800 - 0815 的人员配置记录,以及 1000 - 1045 的另一条人员配置记录。

这是一个解决方案,我找到所有不同的开始和结束时间,然后查询以查看当时有多少其他人打卡。每次答案小于 4 时,您就知道您当时人手不足,大概要等到 NEXT 开始时间。

with meaningfulDtms(meaningfulTime, timeType, group_id)
as
(  
    select distinct StaffingStartTime , 'start' as timeType, group_id
    from DailyRosters 
    union
    select distinct StaffingEndTime , 'end' as timeType, group_id
    from DailyRosters 
)

select COUNT(*), meaningfulDtms.group_id, meaningfulDtms.meaningfulTime
from DailyRosters  dr
inner join meaningfulDtms on dr.group_id = meaningfulDtms.group_id
and (
 (dr.StaffingStartTime  < meaningfulDtms.meaningfulTime
     and dr.StaffingEndTime  >= meaningfulDtms.meaningfulTime
     and meaningfulDtms.timeType = 'start')
 OR
 (dr.StaffingStartTime  <= meaningfulDtms.meaningfulTime
     and dr.StaffingEndTime  > meaningfulDtms.meaningfulTime
     and meaningfulDtms.timeType = 'end')
)
group by meaningfulDtms.group_id, meaningfulDtms.meaningfulTime
having COUNT(*) < 4

创建一个 table,一天中的所有分钟,dt 都在 PK
它将有 1440 行

这不会给你计数为零 - 没有工作人员

select allMiuntes.dt, worktime.grpID, count(distinct(worktime.personID))
  from allMinutes 
  join worktime 
    on allMiuntes.dt > worktime.start 
   and allMiuntes.dt < worktime.end 
 group by allMiuntes.dt, worktime.grpID 
having count(distinct(worktime.personID)) < 3

对于零的时间我认为最好的方法是掌握 grpID
但我不确定这个

select allMiuntes.dt, grpMaster.grpID, count(distinct(worktime.personID))
  from grpMaster
 cross join allMinutes 
  left join worktime 
    on allMiuntes.dt > worktime.start 
   and allMiuntes.dt < worktime.end 
   and worktime.grpID = grpMaster.grpID 
 group by allMiuntes.dt, grpMaster.grpID
having count(distinct(worktime.personID)) < 3