MySQL中如何排除周末并对比当前日期的前两个工作日数据
如何在MySQL中获取当前日期的前两个工作日数据并对比
要解决直接用curdate()-1/curdate()-2会包含周末的问题,你可以通过筛选工作日数据并按日期排序的方式,精准获取最近的两个工作日记录,再进行对比。以下是两种可行方案:
方案一:使用窗口函数(推荐,MySQL 8.0+支持)
这种方法适配多用户场景,自动为每个用户筛选最近两个工作日的数据:
SELECT Name, MAX(CASE WHEN rn = 1 THEN cnt END) AS `T-1`, -- 最近的工作日数据 MAX(CASE WHEN rn = 2 THEN cnt END) AS `T-2`, -- 倒数第二个工作日数据 MAX(CASE WHEN rn = 2 THEN cnt END) - MAX(CASE WHEN rn = 1 THEN cnt END) AS Diff FROM ( SELECT Name, cnt, Dates, -- 按用户分组,日期倒序编号,最近的工作日排第1位 ROW_NUMBER() OVER (PARTITION BY Name ORDER BY Dates DESC) AS rn FROM Acct WHERE Dates < CURDATE() -- 只取当前日期之前的数据 AND WEEKDAY(Dates) BETWEEN 0 AND 4 -- 排除周六(WEEKDAY=5)和周日(WEEKDAY=6) ) t WHERE rn <= 2 -- 只保留前两个工作日的记录 GROUP BY Name;
逻辑说明
- 内层子查询:为每个用户的工作日数据按日期从新到旧编号,最近的工作日标记为
rn=1,倒数第二个为rn=2。 - 外层查询:通过条件聚合将两个工作日的
cnt分别转为T-1和T-2,并计算差值Diff。
当当前日期为2022-07-18(周一)时,查询会自动筛选出2022-07-15(周五,rn=1)和2022-07-14(周四,rn=2)的数据,输出结果完全符合你的需求。
方案二:兼容MySQL 5.7及更早版本(无窗口函数)
如果你的MySQL版本不支持窗口函数,可以用关联子查询实现:
SELECT t.Name, t.cnt AS `T-1`, ( SELECT cnt FROM Acct WHERE Name = t.Name AND Dates < t.Dates AND WEEKDAY(Dates) BETWEEN 0 AND 4 ORDER BY Dates DESC LIMIT 1 ) AS `T-2`, ( SELECT cnt FROM Acct WHERE Name = t.Name AND Dates < t.Dates AND WEEKDAY(Dates) BETWEEN 0 AND 4 ORDER BY Dates DESC LIMIT 1 ) - t.cnt AS Diff FROM ( SELECT Name, cnt, Dates FROM Acct WHERE Dates < CURDATE() AND WEEKDAY(Dates) BETWEEN 0 AND 4 GROUP BY Name HAVING Dates = MAX(Dates) -- 取每个用户最近的工作日数据 ) t;
内容的提问来源于stack exchange,提问作者mohan111
相关产品推荐
相关产品推荐

