需求:給定起迄日期,返回工作日天數(週一至週五),不考慮國定假日。適用於薪資計算、SLA 統計等場景。
DELIMITER //
CREATE FUNCTION workday_diff(start_date DATE, end_date DATE)
RETURNS INT
DETERMINISTIC
NO SQL
BEGIN
DECLARE total_days INT;
DECLARE full_weeks INT;
DECLARE rem_days INT;
DECLARE start_wd INT; -- 1=週一 .. 7=週日
DECLARE workdays INT;
IF start_date > end_date THEN
RETURN -workday_diff(end_date, start_date);
END IF;
SET total_days = DATEDIFF(end_date, start_date) + 1; -- 含首尾
SET full_weeks = total_days DIV 7;
SET rem_days = total_days MOD 7;
SET start_wd = WEEKDAY(start_date) + 1; -- 1=週一
SET workdays = full_weeks * 5;
-- 處理剩餘天數
IF rem_days > 0 THEN
-- 計算剩餘天數中包含多少週六(6)、週日(7)
SET workdays = workdays + rem_days
- IF(6 BETWEEN start_wd AND start_wd + rem_days - 1, 1, 0)
- IF(7 BETWEEN start_wd AND start_wd + rem_days - 1, 1, 0);
END IF;
RETURN workdays;
END //
DELIMITER ;
SELECT workday_diff('2024-01-01', '2024-01-31'); -- 2024 年 1 月工作日數
SELECT workday_diff('2024-01-15', '2024-01-19'); -- 5 (週一至週五)
SELECT workday_diff('2024-01-20', '2024-01-21'); -- 0 (週六週日)
SELECT workday_diff('2024-01-19', '2024-01-22'); -- 1 (週五+週一)
CREATE TABLE holiday (
holiday_date DATE PRIMARY KEY,
name VARCHAR(100)
);
-- 查詢時扣除
SELECT workday_diff('2024-01-01', '2024-12-31')
- (SELECT COUNT(*) FROM holiday
WHERE holiday_date BETWEEN '2024-01-01' AND '2024-12-31'
AND WEEKDAY(holiday_date) NOT IN (5,6)); -- 假日若落在週末不重複扣除