Linq按周再按月分组计算工时跨月周统计异常问题咨询
解决跨月周工时统计归属问题
问题核心
你当前的代码在第一次分组时把Month作为分组键,导致跨月的同一周被拆分成两个独立分组,后续按月汇总时自然无法得到整周的正确累计值。要解决这个问题,必须先按完整的周(不拆分月份)计算单周总工时,再确定该周归属的目标月份,最后按月汇总。
修正思路
- 先按用户+完整周分组:移除分组键中的
Month,确保同一用户的同一周数据被归为一组,计算该周的总工时。 - 确定周的归属月份:根据业务规则(比如取该周最后一天的月份,或者周编号对应的月份——你的例子中2月第5周即使始于1月,也归属2月),为每个周分组标记对应的目标月份。
- 按月+用户汇总:基于周分组的归属月份,重新分组汇总工时。
修正后的代码
// 第一步:按用户+完整周分组,计算单周工时并确定归属月份 var weeklyHours = from t in _db.MyTable group t by new { t.UserId, t.WeekNumber, t.ShiftDate.Year } into weekGroup let weekEndDate = weekGroup.Max(x => x.ShiftDate) // 取该周最后一天,以此确定归属月份 select new { weekGroup.Key.UserId, Week = weekGroup.Key.WeekNumber, Year = weekGroup.Key.Year, TargetMonth = weekEndDate.Month, // 周归属的目标月份 TotalWeeklyHours = weekGroup.Where(x => x.WorkedHours > 37.5).Sum(h => h.Overtime) }; // 第二步:按用户+归属月份分组,汇总月度工时 var monthlyHours = from wh in weeklyHours group wh by new { wh.UserId, wh.TargetMonth, wh.Year } into monthGroup select new { monthGroup.Key.UserId, Year = monthGroup.Key.Year, Month = monthGroup.Key.TargetMonth, TotalMonthlyHours = monthGroup.Sum(x => x.TotalWeeklyHours) };
关键说明
- 添加
Year到分组键:避免跨年时周编号重复导致的分组错误(比如2023年第52周和2024年第52周是不同的周)。 - 周归属月份的规则:示例中用该周的最后一天所在月份作为归属依据,你可以根据业务需求调整(比如取周的第一天、或者周内天数占比更高的月份)。
- 变量名修正:原代码第二个查询存在变量名错误(
month.ShiftDate、day.Key),修正后确保逻辑连贯。
内容的提问来源于stack exchange,提问作者Rowandinho
相关产品推荐
相关产品推荐

