You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL如何获取指定月份的第x个工作日

PostgreSQL实现获取指定月份第x个工作日方案

前提准备

首先你需要提前维护好公共节假日表,存储所有法定节假日日期,示例表结构如下(可根据实际业务调整字段):

CREATE TABLE IF NOT EXISTS public_holidays (
    holiday_date DATE PRIMARY KEY,
    holiday_name VARCHAR(50)
);

方案1:单查询语句实现

适合单次查询场景,逻辑为先生成目标月份的全量日期,过滤掉周末和法定节假日后按日期排序,取序号匹配的日期即可:

WITH month_days AS (
    -- 生成目标月份所有日期,替换'2021-10-01'为你要查询的目标月份任意日期
    SELECT generate_series(
        date_trunc('month', '2021-10-01'::DATE),
        date_trunc('month', '2021-10-01'::DATE) + INTERVAL '1 month - 1 day',
        INTERVAL '1 day'
    )::DATE AS curr_date
),
work_days AS (
    SELECT curr_date,
           ROW_NUMBER() OVER (ORDER BY curr_date) AS work_day_rank
    FROM month_days
    -- 排除周末:PostgreSQL中extract(dow from date)返回0为周日、6为周六
    WHERE extract(dow from curr_date) NOT IN (0,6)
      -- 排除法定节假日
      AND curr_date NOT IN (SELECT holiday_date FROM public_holidays)
)
SELECT curr_date AS target_work_day
FROM work_days
-- 替换3为你要查询的第x个工作日序号
WHERE work_day_rank = 3;

方案2:封装为自定义函数

适合高频调用场景,封装后直接传参即可调用:

CREATE OR REPLACE FUNCTION get_nth_workday(p_target_month DATE, p_nth INT)
RETURNS DATE AS $$
DECLARE
    v_result DATE;
BEGIN
    WITH month_days AS (
        SELECT generate_series(
            date_trunc('month', p_target_month),
            date_trunc('month', p_target_month) + INTERVAL '1 month - 1 day',
            INTERVAL '1 day'
        )::DATE AS curr_date
    ),
    work_days AS (
        SELECT curr_date,
               ROW_NUMBER() OVER (ORDER BY curr_date) AS work_day_rank
        FROM month_days
        WHERE extract(dow from curr_date) NOT IN (0,6)
          AND curr_date NOT IN (SELECT holiday_date FROM public_holidays)
    )
    SELECT curr_date INTO v_result
    FROM work_days
    WHERE work_day_rank = p_nth;

    -- 若输入的序号超过当月工作日总数,抛出异常提示,可根据业务调整返回逻辑
    IF v_result IS NULL THEN
        RAISE EXCEPTION '当月不存在第%个工作日', p_nth;
    END IF;

    RETURN v_result;
END;
$$ LANGUAGE plpgsql STABLE;

函数调用示例

-- 查询2021年10月第3个工作日,输出2021-10-05
SELECT get_nth_workday('2021-10-01', 3);

-- 查询2021年11月第3个工作日,输出2021-11-03
SELECT get_nth_workday('2021-11-01', 3);

内容的提问来源于stack exchange,提问作者Finny

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 08:15:03