创建一个循环以插入日期范围的日期

时间:2017-11-07 03:29:09

标签: postgresql

背景: 员工提交带薪假期请求的假日管理系统。

我需要创造"半天"对于每个员工假期请求的给定日期范围。

来源表: 请求(存储所有请求,每位员工1行)

id (bigint-PK)
begin_date (date)
begin_in_afernoon (bool)
end_date (date)
end_in_morning (bool)
UserID (int)

示例数据:

1 | 08/11/2017 | False | 09/11/2017 | False | 10

目的地表: 的 Half_day_absence

Date (date)
Day_Period (string)
Total
UserID
RequestID

示例数据:

08/11/2017 01:00:00 | AM | 0.5 | 10 | 1
08/11/2017 13:00:00 | PM | 0.5 | 10 | 1
09/11/2017 01:00:00 | AM | 0.5 | 10 | 1
09/11/2017 13:00:00 | PM | 0.5 | 10 | 1

我坚持如何为每个员工请求创建循环,以便在half_day_absence表中插入新行

提前致谢

2 个答案:

答案 0 :(得分:0)

没有经过个人测试..但应该是这种形式的东西:

DO
$$
DECLARE
    rec record;
    nbd integer;
BEGIN
   for rec in select begin_date, begin_in_afernoon, end_date, end_in_morning, userid, EXTRACT('days' FROM (end_date - begin_date)) AS nbdays 
                from holidays;
   LOOP
       nbd = record.nbdays;

       IF end_in_morning = 't' THEN
          INSERT INTO Half_day_absence (begin_date, 'AM', 0.5, record.userid);
       END IF;

       IF end_in_afternoon = 't' THEN
          INSERT INTO Half_day_absence (end_date, 'PM', 0.5, record.userid);
       END IF;

       IF end_in_morning = 'f' AND end_in_afternoon = 'f' THEN
          WHILE nbd > 0 LOOP       
              INSERT INTO Half_day_absence (begin_date + '' || nbd || ''days', 'AM', 0.5, record.userid);
              INSERT INTO Half_day_absence (begin_date + '' || nbd || ''days', 'PM', 0.5, record.userid);
              nbd := nbd - 1;
          END LOOP;
       END IF;

       RETURN next;
   END LOOP;
END
$$;

你是否应该进行更好的时期测试,但这个想法是围绕这个提法。

希望得到这个帮助。

答案 1 :(得分:0)

感谢您的回复。你的代码让我知道如何进行循环。我找到了另一个解决方案,但不需要循环:generate_series()函数。这是我的sql代码片段,如果它可能对某人有帮助:

select 
row_number () over (order by id), --id of new row in destination table
gs as date,
extract(dow from gs) as day_of_week, --Sunday=0/Saturday=6/Monday to Friday=1 à 5
CASE
    WHEN extract(hour from gs) < 13 THEN 'AM'::varchar
    WHEN extract(hour from gs) >=13 THEN 'PM'::varchar
END As day_period
from
(
    select 
    id,
    CASE
        WHEN begin_in_afternoon=false THEN begin_date::date + interval '1' HOUR --business rule: AM started at 1AM
        WHEN begin_in_afternoon=true THEN begin_date::date + interval '13' HOUR --business rule: PM started at 1PM
    END as begin_date,
    CASE
        WHEN end_in_morning=false THEN end_date::date + interval '13' HOUR --business rule: PM started from 1PM
        WHEN end_in_morning=true THEN end_date::date + interval '1' HOUR --business rule: AM started at 1AM
    END as end_date
    from myTable
) h, 
generate_series(h.begin_date, h.end_date, interval '0.5 day')gs
where extract(dow from gs)not in (0,6); --Sunday and Saturday excluded

然后将此SELECT发送到INSERT INTO ..子句以将结果集插入目标表