如何查询含DATETIME类型date列的表中每月最后一分钟的行?
刚好处理过类似的需求!要找出date列值为每月最后一分钟(比如2017-12-31 23:59:00、2017-11-30 23:59:00)的行,核心思路是判断该时间是否等于当月最后一天的23:59:00。下面针对不同主流数据库给出具体的查询语句:
MySQL/MariaDB
可以利用内置的LAST_DAY()函数快速定位当月最后一天,再拼接时间部分进行匹配:
SELECT * FROM your_table WHERE date = CONCAT(LAST_DAY(date), ' 23:59:00');
或者用日期加减的方式更严谨地计算目标时间(避免字符串拼接可能出现的格式问题):
SELECT * FROM your_table WHERE date = DATE_SUB(DATE_ADD(LAST_DAY(date), INTERVAL 1 DAY), INTERVAL 1 MINUTE);
解释:LAST_DAY(date)会返回当前日期所在月份的最后一天(比如2017-12-31),加1天得到下月1号,再减1分钟就精准得到当月最后一天的23:59:00。
PostgreSQL
PostgreSQL可以通过DATE_TRUNC和时间间隔计算来实现:
SELECT * FROM your_table WHERE date = DATE_TRUNC('month', date) + INTERVAL '1 month - 1 minute';
解释:DATE_TRUNC('month', date)会把时间截断到当月第一天(比如2017-11-01 00:00:00),加上1个月得到下月第一天,再减去1分钟就是我们要的月末最后一分钟。
SQL Server
SQL Server用EOMONTH()函数获取月末日期,再拼接时间即可:
SELECT * FROM your_table WHERE date = CONVERT(DATETIME, EOMONTH(date)) + '23:59:00';
也可以用日期偏移的方式计算:
SELECT * FROM your_table WHERE date = DATEADD(MINUTE, -1, DATEADD(MONTH, DATEDIFF(MONTH, 0, date) + 1, 0));
解释:DATEDIFF(MONTH, 0, date)计算从0年到当前日期的总月份数,加1后通过DATEADD得到下月第一天,最后减1分钟就得到目标时间。
通用兼容方案(适用于无内置月末函数的数据库)
如果你的数据库没有直接获取月末的函数,可以通过两个条件组合判断:
- 时间部分是23:59:00
- 当前日期加1天后,月份发生变化(说明是当月最后一天)
SELECT * FROM your_table WHERE DATE_FORMAT(date, '%H:%i:%s') = '23:59:00' AND MONTH(DATE_ADD(date, INTERVAL 1 DAY)) != MONTH(date);
这个方法在跨年份的场景(比如12月31日)也能正常生效,因为1月和12月的月份不同。
注意事项
如果你的date列包含毫秒级别的数据(比如2017-12-31 23:59:00.123),直接匹配会失败,需要先把时间截断到分钟级别。比如在MySQL中可以用TRUNCATE(date, MINUTE)或者DATE_FORMAT(date, '%Y-%m-%d %H:%i:00')处理后再进行匹配。
内容的提问来源于stack exchange,提问作者Shai Givati




