MySQL查询:获取数据表中每月最后日期的全量记录异常排查
解决获取当年每月最后日期全量记录的问题
你遇到的问题核心是日期字段类型不匹配导致的匹配失败:单独查询每月最后日期时返回的是纯日期格式(或时分秒为00:00:00),但表中date字段实际是datetime类型(存储了时分秒信息),直接用=或IN匹配时,只有时分秒完全一致的记录能被选中,其他月份的记录因时分秒不为0,无法匹配成功。
修复方案1:统一转换为日期格式匹配
修改关联查询:
SELECT cpr.* FROM cpr INNER JOIN ( SELECT MAX(`date`) AS max_date FROM cpr WHERE YEAR(`date`) = YEAR(CURRENT_DATE()) GROUP BY YEAR(`date`), MONTH(`date`) ) AS monthwise ON DATE(cpr.`date`) = DATE(monthwise.max_date)
修改IN子查询:
SELECT * FROM cpr WHERE DATE(`date`) IN ( SELECT DATE(MAX(`date`)) FROM cpr WHERE YEAR(`date`) = YEAR(CURRENT_DATE()) GROUP BY YEAR(`date`), MONTH(`date`) )
通过DATE()函数提取日期部分,忽略时分秒的差异,就能匹配到当月最后一天的所有记录。
修复方案2:使用窗口函数(更高效)
窗口函数可以一次扫描表完成逻辑,性能更优,同时天然支持datetime类型的字段:
SELECT * FROM ( SELECT *, RANK() OVER (PARTITION BY YEAR(`date`), MONTH(`date`) ORDER BY `date` DESC) AS rnk FROM cpr WHERE YEAR(`date`) = YEAR(CURRENT_DATE()) ) t WHERE rnk = 1;
这个逻辑是:给当年每个月的记录按date倒序排名,排名为1的就是当月最后日期的所有记录(不管时分秒是什么,只要是当月最晚的日期的记录都会被选中)。
验证说明
如果你的date字段确实是datetime类型,执行原查询时,子查询返回的max_date是该月的最晚datetime(比如2023-02-27 23:59:59),但表中该月的记录可能没有这个精确时间,导致匹配失败。而转换为日期格式或用窗口函数,就能避开时分秒的干扰,正确获取所有目标记录。
内容的提问来源于stack exchange,提问作者Ramisha Mukhtar
相关产品推荐
相关产品推荐

