基于不同条件多次查询同一列数据的SQL实现:楼层耗电量统计
解决过去7天各楼层每日总耗电量统计问题
看来你遇到了一个分组统计的常见问题,咱们一步步拆解解决它!
首先我先假设你的数据库表结构大概是这样的(如果实际结构不同,你可以对应调整字段名):
- 表名:
floor_power_consumption - 字段:
floor_number(楼层编号,比如1/2/3)、consumption(单条记录的耗电量)、record_date(记录生成的日期/时间)
为什么只能查到1楼的数据?
大概率是这两个原因之一:
- 你的查询语句里不小心加了
floor_number = 1的过滤条件,限制了只查询1楼; - 分组逻辑不对,只按日期分组而没按楼层分组,导致结果是所有楼层的总和(或者因为1楼数据占比高被你误以为只查到1楼);
- 极端情况:2、3楼过去7天没有数据,但你说系统每日自动插入3条,所以这个可能性较低,可以先验证数据是否存在。
正确的SQL查询语句
下面这个语句可以统计过去7天每个楼层的每日总耗电量,同时返回所有楼层的数据:
SELECT floor_number, DATE(record_date) AS daily_date, SUM(consumption) AS daily_total_consumption FROM floor_power_consumption -- 过滤过去7天的记录(包含今天) WHERE DATE(record_date) >= CURDATE() - INTERVAL 7 DAY -- 关键:必须同时按楼层和日期分组,才能得到每个楼层每天的单独统计 GROUP BY floor_number, DATE(record_date) -- 按日期倒序、楼层排序,方便查看最新数据 ORDER BY daily_date DESC, floor_number;
语句解释
DATE(record_date):如果record_date是带时间的DATETIME/TIMESTAMP类型,用这个函数把时间部分截断,确保同一天的所有记录会被归为一组;如果record_date本身就是DATE类型,直接用record_date即可。SUM(consumption):对同一楼层同一天的所有耗电量记录求和,得到当日总耗电。GROUP BY floor_number, DATE(record_date):这是核心!只有同时按楼层和日期分组,才能区分开不同楼层的每日数据,而不是把所有楼层的数据混在一起统计。
验证2、3楼是否有数据
如果你执行上面的语句还是看不到2、3楼的数据,可以先跑这个查询确认过去7天各楼层的记录数:
SELECT floor_number, COUNT(*) AS record_count FROM floor_power_consumption WHERE DATE(record_date) >= CURDATE() - INTERVAL 7 DAY GROUP BY floor_number;
如果2、3楼的record_count是0,那你需要检查系统自动插入数据的逻辑是否正常。
进阶:包含无数据的日期(显示0)
如果需要保证每个楼层每天都有一条记录(哪怕当天没有耗电数据,显示0),可以用递归CTE生成连续日期,再关联楼层表(以MySQL为例):
-- 生成过去7天的连续日期 WITH RECURSIVE date_range AS ( SELECT CURDATE() - INTERVAL 7 DAY AS date_val UNION ALL SELECT date_val + INTERVAL 1 DAY FROM date_range WHERE date_val < CURDATE() ), -- 列出所有需要统计的楼层 floors AS ( SELECT 1 AS floor_num UNION ALL SELECT 2 UNION ALL SELECT 3 ) SELECT f.floor_num AS floor_number, dr.date_val AS daily_date, -- 如果没有数据,用COALESCE返回0 COALESCE(SUM(p.consumption), 0) AS daily_total_consumption FROM floors f -- 交叉连接得到所有楼层+日期的组合 CROSS JOIN date_range dr -- 左连接耗电量表,匹配对应楼层和日期的数据 LEFT JOIN floor_power_consumption p ON f.floor_num = p.floor_number AND DATE(p.record_date) = dr.date_val GROUP BY f.floor_num, dr.date_val ORDER BY dr.date_val DESC, f.floor_num;
内容的提问来源于stack exchange,提问作者Callum
相关产品推荐
相关产品推荐

