根据开始日期和结束日期列计算并发记录
Counting concurrent records based on startdate and enddate columns
table结构:
人事记录
- PersonnelId 整数
- GroupId 整数
- StaffingStartDateTime 日期时间
- StaffingEndDateTime 日期时间
如何在给定日期和员工所属的组 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
table结构:
人事记录
- PersonnelId 整数
- GroupId 整数
- StaffingStartDateTime 日期时间
- StaffingEndDateTime 日期时间
如何在给定日期和员工所属的组 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