SQL动态筛选每月最后可用日期 按月分组过滤最大值查询需求
实现每月最后可用日期数据筛选并显示当月第一天的SQL方案
核心思路是先定位每个月份的最后有效日期,再匹配原数据,最后将日期转换为当月第一天。以下是主流数据库的实现代码:
MySQL 版本
SELECT DATE_FORMAT(t1.date_column, '%Y-%m-01') AS month_first_day, -- 替换为你需要的具体字段,比如 t1.value, t1.id 等 t1.* FROM your_table t1 INNER JOIN ( -- 分组计算每个月的最后可用日期 SELECT DATE_FORMAT(date_column, '%Y-%m') AS month_key, MAX(date_column) AS last_valid_date FROM your_table GROUP BY DATE_FORMAT(date_column, '%Y-%m') ) t2 ON DATE_FORMAT(t1.date_column, '%Y-%m') = t2.month_key AND t1.date_column = t2.last_valid_date;
SQL Server 版本
SELECT DATEFROMPARTS(YEAR(t1.date_column), MONTH(t1.date_column), 1) AS month_first_day, -- 替换为你需要的具体字段 t1.* FROM your_table t1 INNER JOIN ( SELECT DATEFROMPARTS(YEAR(date_column), MONTH(date_column), 1) AS month_start, MAX(date_column) AS last_valid_date FROM your_table GROUP BY DATEFROMPARTS(YEAR(date_column), MONTH(date_column), 1) ) t2 ON DATEFROMPARTS(YEAR(t1.date_column), MONTH(t1.date_column), 1) = t2.month_start AND t1.date_column = t2.last_valid_date;
PostgreSQL 版本
SELECT DATE_TRUNC('month', t1.date_column)::DATE AS month_first_day, -- 替换为你需要的具体字段 t1.* FROM your_table t1 INNER JOIN ( SELECT DATE_TRUNC('month', date_column)::DATE AS month_start, MAX(date_column) AS last_valid_date FROM your_table GROUP BY DATE_TRUNC('month', date_column)::DATE ) t2 ON DATE_TRUNC('month', t1.date_column)::DATE = t2.month_start AND t1.date_column = t2.last_valid_date;
注意事项
- 把
your_table替换成你的实际表名,date_column替换为存储日期的字段名 - 避免直接使用
t1.*,建议明确写出需要展示的字段,减少冗余数据 - 如果同一月份的最后有效日期有多条数据,上述代码会全部保留;若只需单条,可在子查询中添加
ROW_NUMBER()窗口函数进行筛选,示例(以MySQL 8.0+为例):
WITH ranked_data AS ( SELECT *, ROW_NUMBER() OVER(PARTITION BY DATE_FORMAT(date_column, '%Y-%m') ORDER BY date_column DESC) AS rn FROM your_table ) SELECT DATE_FORMAT(date_column, '%Y-%m-01') AS month_first_day, -- 具体字段 id, value FROM ranked_data WHERE rn = 1;
内容的提问来源于stack exchange,提问作者RobbeVL
相关产品推荐
相关产品推荐

