PL/SQL中嵌套循环计算不同ID近40天时长平均值的疑问
计算多ID近40天时长平均值的解决方案
你的思路优化(替代二维数组)
你想用累加后求平均的思路是对的,但二维数组不是最优选择——用**哈希表(字典)**来存储每个ID的总时长和统计天数,能直接通过ID快速定位,避免遍历数组找位置的麻烦:
- 初始化一个字典,键是ID,值存两个数据:总时长(转成秒数方便计算)、统计到的天数
- 遍历每天的数据时,对每个ID计算当日时长(把HH:MI:SS转成秒数,注意处理跨天的情况,比如结束时间早于开始时间时,要加86400秒)
- 把当日时长累加到对应ID的总时长里,同时统计天数+1
- 最后每个ID的平均值 = 总时长 / 天数(如果确定每天都有该ID的数据,直接除以40即可)
- 把平均秒数再转回HH:MI:SS格式
示例代码(Python)
# 初始化统计字典:key=ID,value存储总秒数和天数 id_stats = {} # 假设daily_data是你从游标获取的40天数据,每天是一个包含所有ID记录的列表 for day_records in daily_data: for record in day_records: current_id = record["id"] start = record["start_time"] end = record["end_time"] # 把HH:MI:SS转成总秒数 def time_to_sec(time_str): h, m, s = map(int, time_str.split(":")) return h * 3600 + m * 60 + s day_sec = time_to_sec(end) - time_to_sec(start) # 处理跨天的情况(比如结束时间是次日凌晨) if day_sec < 0: day_sec += 86400 # 更新统计 if current_id not in id_stats: id_stats[current_id] = {"total_sec": 0, "days": 0} id_stats[current_id]["total_sec"] += day_sec id_stats[current_id]["days"] += 1 # 计算平均值并转回时间格式 id_avg = {} for idx, stats in id_stats.items(): avg_sec = stats["total_sec"] / stats["days"] # 转成HH:MI:SS h = int(avg_sec // 3600) m = int((avg_sec % 3600) // 60) s = int(avg_sec % 60) id_avg[idx] = f"{h:02d}:{m:02d}:{s:02d}" # 输出结果 for idx, avg_time in id_avg.items(): print(f"ID{idx}近40天平均时长:{avg_time}")
更优解决方案:直接用数据库计算
如果你的数据存在数据库里,完全不需要拉到程序里循环计算——让数据库直接分组统计,效率更高,代码更简洁:
示例SQL(MySQL)
假设你的表结构是 daily_records(id, record_date, start_time, end_time),执行以下语句就能直接得到每个ID的近40天平均时长:
SELECT id, SEC_TO_TIME(AVG(TIME_TO_SEC(TIMEDIFF(end_time, start_time)))) AS average_duration FROM daily_records WHERE record_date >= DATE_SUB(CURDATE(), INTERVAL 40 DAY) GROUP BY id;
逻辑说明:
TIMEDIFF(end_time, start_time):计算当日时长TIME_TO_SEC():把时长转成秒数,方便求平均AVG():对每个ID的秒数取平均SEC_TO_TIME():把平均秒数转回HH:MI:SS格式GROUP BY id:按ID分组统计
内容的提问来源于stack exchange,提问作者Luca
相关产品推荐
相关产品推荐

