为了获得工作日的计数,您需要使用 date_trunc() 函数知道该月的第一天的日期 (start_date)。之后,您需要使用extract() 函数获取特定月份的天数 (month_last_day),对此有一个wiki page。最后,您可以使用start_date 日期和month_last_day 数字generate_series() 天数排除使用date_part() 函数的周末天数。
CREATE OR REPLACE FUNCTION extract_month_business_days(d DATE, count_remaining BOOLEAN)
RETURNS INTEGER AS $$
DECLARE
start_date DATE;
month_last_day INTEGER;
result INTEGER;
BEGIN
IF count_remaining THEN
start_date = d;
ELSE
start_date = date_trunc('month',d);
END IF;
month_last_day = extract(DAY FROM date_trunc('month',d) + INTERVAL '1 MONTH - 1 day');
SELECT count(*) INTO result FROM generate_series(0,(month_last_day - extract(DAY FROM start_date))::INTEGER) day
WHERE date_part('dow', start_date + day) NOT IN (0,6);
RETURN result;
END;
$$ LANGUAGE plpgsql;
结果:
WITH t(dates) AS ( VALUES
('2016-02-18'::DATE),
('2016-03-18'::DATE),
('2016-04-18'::DATE),
('2016-05-18'::DATE)
)
SELECT
to_char(dates,'Month YY') AS month,
extract_month_business_days(dates,FALSE) AS number_business_days,
extract_month_business_days(dates,TRUE) AS remaining_business_days
FROM t;
month | number_business_days | remaining_business_days
--------------+----------------------+-------------------------
February 16 | 21 | 8
March 16 | 23 | 10
April 16 | 21 | 10
May 16 | 22 | 10
(4 rows)
更新 - 红移版
正如 @John 指出的,generate_series() 在 AWS Redshift 中不可用,函数定义如下:
CREATE OR REPLACE FUNCTION extract_month_business_days(d DATE, count_remaining BOOLEAN)
RETURNS INTEGER AS $$
DECLARE
start_date DATE;
month_last_day INTEGER;
result INTEGER;
i INTEGER;
BEGIN
result = 0;
IF count_remaining THEN
start_date = d;
ELSE
start_date = date_trunc('month',d);
END IF;
month_last_day = extract(DAY FROM date_trunc('month',d) + INTERVAL '1 MONTH - 1 day');
result = 0;
FOR i IN 0..(month_last_day - extract(DAY FROM start_date))::INTEGER LOOP
IF (date_part('dow', start_date + i) NOT IN (0,6)) THEN
result = result + 1;
END IF;
END LOOP;
RETURN result;
END;
$$ LANGUAGE plpgsql;