SQL查询:如何获取15个实际日期的累计数据(含无数据日,排除周日)
解决方法:获取最新15个有记录的非周日日期数据
你的需求是拿到最新的15个存在业务记录且非周日的日期的数据,而非按日历跨度取15天(这种方式会因缺失记录导致结果条数不足)。原SQL的问题在于用日期范围筛选,而非直接锁定15个有效日期,下面提供两种可行方案:
方案一:先筛选目标日期再关联统计
先从表中提取最新的15个非周日且有记录的日期,再基于这些日期做数据统计:
SELECT COUNT(name) AS days, SUM(act_del_stops + act_pu_stops) AS stops, SEC_TO_TIME(SUM(TIME_TO_SEC(on_road_hrs))) AS on_rh, date AS date3 FROM service_data WHERE date IN ( -- 子查询:获取最新15个非周日的有效日期 SELECT DISTINCT date FROM service_data WHERE dayofweek(date) > 1 ORDER BY date DESC LIMIT 15 ) GROUP BY date ORDER BY date ASC;
方案二:用窗口函数标记日期排名
如果你的数据库支持窗口函数(如MySQL 8.0+、PostgreSQL等),可以通过ROW_NUMBER()给日期排序,再筛选排名前15的记录:
WITH ranked_dates AS ( SELECT date, -- 按日期倒序排名,仅非周日的日期参与排名 ROW_NUMBER() OVER (ORDER BY date DESC) AS date_rank FROM service_data WHERE dayofweek(date) > 1 GROUP BY date ) SELECT COUNT(sd.name) AS days, SUM(sd.act_del_stops + sd.act_pu_stops) AS stops, SEC_TO_TIME(SUM(TIME_TO_SEC(sd.on_road_hrs))) AS on_rh, sd.date AS date3 FROM service_data sd JOIN ranked_dates rd ON sd.date = rd.date WHERE rd.date_rank <= 15 GROUP BY sd.date ORDER BY sd.date ASC;
注意事项
- 不同数据库的星期函数逻辑有差异:比如MySQL中
dayofweek(date)返回1代表周日,7代表周六;PostgreSQL则用extract(dow from date),返回0为周日、6为周六,若使用其他数据库,需对应调整排除周日的条件。 - 两种方案都能确保拿到恰好15个有效日期的数据,无论这些日期之间的间隔长短,只取最新的、有记录且非周日的15天。
内容的提问来源于stack exchange,提问作者drodsher
相关产品推荐
相关产品推荐

