为日本一家公司解决问题。政府有一些规定,比如。。。如果您持有工作签证:
在一家公司工作三年以上不能不请30天假
你不能在同一家人事公司工作超过5年而不请6个月的假
所以我们想知道在接下来的30/60/90天里是否有人会违反这两条规则。
样本数据(合同清单):
if object_id('tempdb..#sampleDates') is not null drop table #sampleDates
create table #sampleDates (UserId int, CompanyID int, WorkPeriodStart datetime, WorkPeriodEnd datetime)
insert #sampleDates (UserId, CompanyID, WorkPeriodStart, WorkPeriodEnd) values (27809, 972, '2019-10-10', '2020-10-10')
insert #sampleDates (UserId, CompanyID, WorkPeriodStart, WorkPeriodEnd) values (27853, 484, '2019-10-10', '2020-10-10')
insert #sampleDates (UserId, CompanyID, WorkPeriodStart, WorkPeriodEnd) values (27856, 172, '2019-10-10', '2020-10-10')
insert #sampleDates (UserId, CompanyID, WorkPeriodStart, WorkPeriodEnd) values (27857, 1234, '2015-01-01', '2015-12-31')
insert #sampleDates (UserId, CompanyID, WorkPeriodStart, WorkPeriodEnd) values (27857, 1234, '2016-01-01', '2017-02-28')
insert #sampleDates (UserId, CompanyID, WorkPeriodStart, WorkPeriodEnd) values (27857, 1234, '2017-01-01', '2017-12-31')
insert #sampleDates (UserId, CompanyID, WorkPeriodStart, WorkPeriodEnd) values (27857, 1234, '2018-01-01', '2018-12-31')
insert #sampleDates (UserId, CompanyID, WorkPeriodStart, WorkPeriodEnd) values (27857, 1234, '2019-01-01', '2020-01-31')
insert #sampleDates (UserId, CompanyID, WorkPeriodStart, WorkPeriodEnd) values (27857, 1234, '2020-01-01', '2020-12-31')
insert #sampleDates (UserId, CompanyID, WorkPeriodStart, WorkPeriodEnd) values (27897, 179, '2019-10-10', '2020-10-10')
我的第一个问题可能是日期重叠。我已经接近一个解决方案,但直到我知道如何解决x年/y天的工作休假问题,我不知道我的cte或temp表的输出应该是什么样的。
我不希望有人帮我做这项工作,但我想找一篇文章,可以告诉我:
我如何确定某人是否在这段时间内休息过,休息了多长时间(日期范围之间的间隔)?
我怎么知道他们在接下来的30/60/90天里是否已经工作了3/5年而没有30/180天的休息时间?
这看起来很简单,直到我开始编写程序。
谢谢你的帮助。
编辑:
值得一提的是,这是我在消除重叠日期方面的第二次工作尝试(第一个版本使用了密集排序方法,它一直有效,直到我搞砸了一些事情,使用了一些简单的方法):
;with CJ as (
select UserId, CompanyID, WorkPeriodStart, WorkPeriodEnd from #sampleDates c
)
select
c.CompanyID,
c.WorkPeriodStart,
min(t1.WorkPeriodEnd) as EndDate
from CJ c
inner join CJ t1 on c.WorkPeriodStart <= t1.WorkPeriodEnd and c.UserId = t1.UserId and c.CompanyID = t1.CompanyID
and not exists(select * from CJ t2 where t1.UserId = t2.UserId and t1.CompanyID = t2.CompanyID and t1.WorkPeriodEnd >= t2.WorkPeriodStart AND t1.WorkPeriodEnd < t2.WorkPeriodEnd)
where not exists(select * from CJ c2 where c.UserId = c2.UserId and c.CompanyID = c2.CompanyID and c.WorkPeriodStart > c2.WorkPeriodStart AND c.WorkPeriodStart <= c2.WorkPeriodEnd)
group by c.UserId, c.CompanyID, c.WorkPeriodStart
order by c.UserId, c.WorkPeriodStart
3条答案
按热度按时间oipij1gg1#
免责声明:这是一个不完整的答案。
我可以稍后继续,但这展示了如何计算岛屿。那么识别罪犯就不那么复杂了。
参见增强示例。我添加了用户
27897
它有三个岛:0、1和2。见下表:使用此数据,为每行计算孤岛的查询可以如下所示:
结果:
现在,我们可以通过执行以下操作来扩充此查询,以获取每个岛的“工作日”和每个岛之前的“休假日”:
结果:
这个结果非常接近你所需要的。这些数据实际上对根据条件筛选行很有用。
qvtsj1bj2#
此脚本合并任何重叠的工作期间,然后计算前3年和5年期间的总工作天数。然后获取该值并确定该值是否超过该期间内允许的最大工作日
UserId
以及CompanyId
三年的期限UserId
5年期限(这是对你问题中规则的正确解释吗?)从这一点,然后简单地增加
30
,60
以及90
总天数,看看更大的价值是否会超过各自的限制。考虑到不同的分组规则,这将作为2个查询(没有重复的UserId
但结果仍然是反对任何违规行为的标志UserId
.在下面的示例中,您可以看到
UserId = 27857
目前只违反了5年的规定,然后又违反了3年的规定,他们应该再留任一年吗60
天。此外,UserId = 27858
目前还可以,但将违反5年规则60
天。我对你如何定义一年以及你的工作是否
WorkPeriodEnd
值是否包含,因此请检查所需的逻辑是否正确应用。脚本
输出
bvk5enib3#
这就是我的结局。
<无用的计划>
我一直面临的问题是:
我如何处理任何和所有日期范围重叠,并确定合同日期范围内的天数。
客户端仍在使用SQL2008,所以我需要一些旧的(er)学校tsql。
确保准确计算中断时间(合同之间的时间)。
所以我选择了我自己的解决方案,这可能是愚蠢的,因为它需要在内存中为每个工作日/候选组合生成一个记录。我看合同表没有超出5-10公里的记录范围。我要往这个方向走的唯一原因。
我创建了一个日历表,其中包含从1980年1月1日到2050年12月31日的所有日期,然后通过candidateid将合同范围加入日历表。这些将是工作日期。日历表中与合同范围内的日期不匹配的任何日期都是休息日。
日历表
5年违规查询(工作5年,没有6个月的冷静期)