MySQL按用户统计项目内近7天时间总和及零工时用户展示问题
解决项目用户近7天工时统计的两个问题
折腾4天确实够闹心的,我来帮你把这两个问题拆解清楚,一步到位解决:
核心问题根源
- 时长求和逻辑错误:直接对
DATETIME/TIME类型的date_time字段用SUM()是行不通的——数据库不会自动把它当成时长累加,必须先转成秒数计算总和,再转回时间格式。 - 缺失未工作用户:你大概率用了
INNER JOIN,它只会保留两边表都有匹配数据的用户。换成LEFT JOIN才能把项目下所有用户都留住,哪怕他们没有任何工时记录。
分场景的SQL解决方案
先基于常规的表结构给出示例(如果你的字段名/表名不同,直接替换就行):
users表:存储用户基础信息,包含user_id(主键)、usernametimers表:存储工时记录,包含user_id(关联用户)、project_id(关联项目),以及和时长相关的字段
场景1:timers.date_time就是单条工时的时长(比如存01:20:00这类格式)
SELECT u.username, -- 用COALESCE把无工时的NULL结果转成00:00:00 COALESCE(SEC_TO_TIME(SUM(TIME_TO_SEC(t.date_time))), '00:00:00') AS total_duration FROM users u -- 如果是项目专属用户,先关联项目用户表(比如project_users) -- JOIN project_users pu ON u.user_id = pu.user_id AND pu.project_id = 你的项目ID LEFT JOIN timers t ON u.user_id = t.user_id AND t.project_id = 你的项目ID -- 指定要统计的项目ID AND t.work_date >= DATE_SUB(CURDATE(), INTERVAL 7 DAY) -- 筛选近7天的工时记录 GROUP BY u.user_id, u.username;
场景2:timers.date_time是工时开始时间,另有end_time字段存结束时间
这种情况需要先计算单条工时的时长,再求和:
SELECT u.username, COALESCE(SEC_TO_TIME(SUM(TIMESTAMPDIFF(SECOND, t.date_time, t.end_time))), '00:00:00') AS total_duration FROM users u LEFT JOIN timers t ON u.user_id = t.user_id AND t.project_id = 你的项目ID AND t.date_time >= DATE_SUB(NOW(), INTERVAL 7 DAY) -- 筛选近7天的工时开始时间 GROUP BY u.user_id, u.username;
关键细节提醒
- 筛选条件别放错位置:近7天的条件一定要写在
LEFT JOIN的ON子句里,不能写在WHERE中!否则会把没有工时的用户过滤掉,相当于变回INNER JOIN。 COALESCE的必要性:没有工时记录的用户,SUM()的结果是NULL,这个函数能帮你把它转换成你需要的00:00:00格式。- 分组要精准:
GROUP BY必须包含用户的唯一标识(比如user_id),避免重名用户的统计结果出错。
内容的提问来源于stack exchange,提问作者Kevin Parks
相关产品推荐
相关产品推荐

