这在没有日历表和月份的情况下有效。而且您只需要更改日期值@curdt 变量。它可以是该月内的任何日期,只要它不小于或大于实际日历日期,例如“2019-07-00”或“2019-07-32” - 这是行不通的。
#1 : Setting variable.
SET @curdt := '2019-07-01'; #only need to change the date here.
SET @startdate := LAST_DAY(@curdt-INTERVAL 1 MONTH)+INTERVAL 1 DAY;
SET @lastdate := LAST_DAY(@curdt);
#2 : Count workdays.
SELECT SUM(CASE WHEN DAY(dt) <= 15 AND WEEKDAY(dt)=6 THEN 0
WHEN DAY(dt) > 15 AND WEEKDAY(dt) IN (5,6) THEN 0
ELSE 1 END) AS Workdays
FROM
(SELECT dt
FROM (
#custom calendar
SELECT CONCAT_WS('-',curmy,CONCAT(n2,n1)) dt
FROM
(SELECT 0 AS n1 UNION
SELECT 1 UNION
SELECT 2 UNION
SELECT 3 UNION
SELECT 4 UNION
SELECT 5 UNION
SELECT 6 UNION
SELECT 7 UNION
SELECT 8 UNION
SELECT 9 ) a CROSS JOIN
(SELECT 0 n2 UNION
SELECT 1 UNION
SELECT 2 UNION
SELECT 3) b CROSS JOIN
(SELECT LEFT(@curdt,7) curmy) c
) zz
WHERE dt BETWEEN @startdate AND @lastdate) XX
GROUP BY MONTH(dt);
刚刚尝试了一个新查询,可能只是在此处添加以供将来参考:
SET @curdate := CURDATE()-INTERVAL 1 MONTH;
SELECT * FROM
(SELECT CONCAT_WS('-',df,CONCAT(b,c)) dm FROM
(SELECT DATE_FORMAT(@curdate, '%Y-%m') df) a CROSS JOIN
(SELECT 0 b UNION SELECT 1 b UNION SELECT 2 UNION SELECT 3) b CROSS JOIN
(SELECT 0 c UNION
SELECT 1 UNION
SELECT 2 UNION
SELECT 3 UNION
SELECT 4 UNION
SELECT 5 UNION
SELECT 6 UNION
SELECT 7 UNION
SELECT 8 UNION
SELECT 9) c) d WHERE DAY(dm) BETWEEN 1 AND DAY(LAST_DAY(dm))
ORDER BY dm;
此方法适用于 MariaDB - 使用它的序列引擎:
From MariaDB 10.1, the Sequence engine is installed by default.
SELECT DATE_FORMAT(CONCAT_WS('-',a.seq,b.seq,c.seq), '%Y-%m-%d') dates
FROM seq_2020_to_2021 a -- year range
CROSS JOIN seq_1_to_12 b -- month range
CROSS JOIN seq_1_to_31 c -- day range
HAVING dates IS NOT NULL; -- excluding invalid dates returned as NULL