簡體   English   中英

如何根據PL / pgSQL中的開始日期和持續時間(工作日)獲取結束日期?

[英]How to get end date based on a start date and duration (workdays) in PL/pgSQL?

我需要根據開始日期和持續時間( 表示工作日數的整數)計算作業的結束日期。

我已經根據這個答案編寫了一個函數,它計算兩個日期(開始和虛擬結束)之間的周末天數。

-- 0 Sunday
-- 1 Monday
-- 2 Tuesday
-- 3 Wednesday
-- 4 Thursday
-- 5 Friday
-- 6 Saturday
CREATE OR REPLACE FUNCTION weekend_days(date, date) RETURNS INT AS
$$
SELECT COUNT(days)::INT
    FROM generate_series($1, $2, '1 day') AS days
    WHERE EXTRACT(DOW FROM days) BETWEEN 1 AND 5;
$$
LANGUAGE 'sql' IMMUTABLE STRICT;

我想創建一個觸發器ON INSERT或ON UPDATE,它將填充相應的end_date列。 顯然,將周末天數添加到給定的持續時間並不能解決問題。

遞歸

有沒有辦法讓遞歸功能繼續添加周末或假期?

編輯:也許在這個答案中可以找到另一個很好的例子,那就是周末和假期。

CREATE OR REPLACE FUNCTION is_business_day(p_date date)
  RETURNS boolean AS
$BODY$
DECLARE
    is_business_day boolean;
    dow int;
BEGIN
    dow := extract('dow' from p_date);

    IF dow = 6 OR dow = 0
        THEN
        is_business_day := FALSE;
    ELSE
        is_business_day := TRUE;
    END IF;

    RETURN is_business_day ;
END;
$BODY$
  LANGUAGE plpgsql IMMUTABLE;



CREATE OR REPLACE FUNCTION working_date(date start_date, int duration)
  RETURNS date AS
$BODY$
DECLARE 
    ret_date date;
    loop_date date;
BEGIN   
    --add days
    ret_date := start_date + (duration - 1);

    loop_date := start_date + 1; 
    --add extra day for each no business day between start_date and ret_date
    WHILE loop_date <= ret_date LOOP
        IF not is_business_day(loop_date) THEN
            ret_date := ret_date + 1;
        END IF;
        loop_date := loop_date + 1;
    END LOOP;
    --add day if ret_date is no business day
    WHILE not is_business_day(ret_date) LOOP
        ret_date := ret_date + 1;
    END LOOP;

    RETURN ret_date;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE SECURITY DEFINER
  COST 100;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM