SQL 服务器创建班次安排 4 年 4 休,假期 4 班

SQL Server Create Shift Schedule 4 on 4 off for year with holidays for 4 shifts

我需要制定一个轮班时间表,它每年都需要完成,所以我想编写它。

我有 4 个班次,每个班次都有自己的开始停止时间(通常是相同的模式) 像 A / B 是早上 8 点到晚上 8 点(4 天)然后 C / D 晚上 8 点到早上 8 点(4 天) 班次交替 A/B 4 天,然后 C / D 4 天。

我知道有人这样做了,但我需要帮助才能知道如何或从哪里开始使用代码。 我知道我需要一个 table 的班次及其开始和停止时间,一个 table 的假期(也许 - 我认为可能有一些内置的东西可以做到这一点)。

然后我需要时间表的实际 table .. 班次、开始、停止、Day/Night、假期。 工作 4 天,休息 4 天 - 如果我提供 12 月 28 日的开始日期,则按月提供一年的完整时间表。

我怎样才能做到这一点?

我发现这个 gem 可以日复一日地进行年度化,我想我需要查找一些数学知识才能让它迭代 4 on 4 off 并且可能加入两个 table s

我不知道这是否适合您使用。尽管如此,这里有一个脚本可以在跳过假期列表的同时生成轮班列表。虽然内置了大量假设,但适应类似模式应该不会非常困难:

with const as (
   select cast('20211228' as date) as basedate, 8 as cycle_length
), holidays as (
    select holiday
    from const cross apply (values
        (datefromparts(year(basedate) + 1,  2, 14)),
        (datefromparts(year(basedate) + 1,  3, 17)),
        (datefromparts(year(basedate) + 1,  7,  4)),
        (datefromparts(year(basedate) + 1, 10, 31)) 
    ) as h(holiday)
), numbers as (
    select n
    from (values (0), (1), (2), (3), (4), (5), (6), (7), (8), (9)) as n(n)
), cycles as (
    select cycle.n + (n0.n + 10 * n1.n) * cycle_length as daynum
    from numbers n0 cross join numbers n1 cross join numbers cycle cross join const
    where cycle.n < cycle_length and cycle.n + (n0.n + 10 * n1.n) * cycle_length < 367
)
select schedule_date, description
    from const cross apply cycles cross apply
        (select dateadd(day, daynum, basedate) as dt) d cross apply
        (select count(*) from holidays where holiday <= dt) h(skips) cross apply
        (select n from numbers where n in (1, 2)) s(shift) cross apply
        (values (
                dateadd(day, skips, dt),
                case daynum / (cycle_length / 2) % 2
                    when 0 then case shift when 1 then 'A 8am-8pm' else 'B 8pm-8am' end
                    when 1 then case shift when 1 then 'C 8am-8pm' else 'D 8pm-8am' end
                end
        )) v2(schedule_date, description)
    order by schedule_date;

https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=1d03e27163bd37484d2d5c288eb9e80c