取得「當前日期往前推 5 個工作日」的日期,週六、週日不計算在內;節假日同理。
CREATE TABLE calendar (
cal_date DATE PRIMARY KEY,
is_workday TINYINT(1) NOT NULL DEFAULT 1, -- 1=工作日 0=休息日
memo VARCHAR(50)
);
-- 初始化 10 年資料
INSERT INTO calendar (cal_date, is_workday)
SELECT d, CASE WHEN DAYOFWEEK(d) IN (1,7) THEN 0 ELSE 1 END
FROM (
SELECT DATE_ADD('2020-01-01', INTERVAL seq DAY) AS d
FROM seq_0_to_3650 -- 需自建序列表或遞迴 CTE
) t;
SELECT MAX(cal_date) AS target_date
FROM calendar
WHERE cal_date < CURDATE()
AND is_workday = 1
AND (
SELECT COUNT(*) FROM calendar c2
WHERE c2.cal_date <= calendar.cal_date
AND c2.cal_date < CURDATE()
AND c2.is_workday = 1
) <= 5;
WITH RECURSIVE workdays AS (
SELECT DATE_SUB(CURDATE(), INTERVAL 1 DAY) AS d, 1 AS cnt
UNION ALL
SELECT DATE_SUB(d, INTERVAL 1 DAY),
cnt + CASE WHEN DAYOFWEEK(DATE_SUB(d, INTERVAL 1 DAY)) IN (1,7) THEN 0 ELSE 1 END
FROM workdays
WHERE cnt < 5
)
SELECT d FROM workdays WHERE cnt = 5 ORDER BY d DESC LIMIT 1;
在 calendar 表手動將節假日 is_workday=0,或建立 holiday 表 LEFT JOIN 排除。純 SQL 方案則需在 CTE 中硬編碼或 NOT IN (SELECT holiday_date FROM holidays)。
(is_workday, cal_date),查詢極快且易維護。