#!/usr/bin/env python3 """L2 每个课时首次通关耗时统计""" import psycopg2 import sys conn = psycopg2.connect( host="bj-postgres-16pob4sg.sql.tencentcdb.com", port=28591, user="ai_member", password="LdfjdjL83h3h3^$&**YGG*", dbname="vala_bi" ) cur = conn.cursor() # 获取 L2 所有章节 cur.execute(""" SELECT id, course_season, course_unit, course_lesson FROM bi_level_unit_lesson WHERE course_level = 'L2' ORDER BY course_season, course_unit, course_lesson """) chapters = cur.fetchall() results = [] for cid, season, unit, lesson in chapters: # 从8张分表收集该章节的首次完成记录 first_dones = {} # (user_id, chapter_unique_id) -> first_done_time for tbl_idx in range(8): cur.execute(f""" SELECT user_id, chapter_unique_id, MIN(created_at) FROM bi_user_chapter_play_record_{tbl_idx} WHERE play_status = 1 AND chapter_id = {cid} GROUP BY user_id, chapter_unique_id """) for row in cur.fetchall(): uid, cu_id, ts = row key = (uid, cu_id) if key not in first_dones or ts < first_dones[key][0]: first_dones[key] = (ts, cu_id) if not first_dones: results.append((season, unit, lesson, cid, 0, 0.0)) continue # 对每个首次完成记录,统计组件总耗时 total_times = [] for (uid, cu_id), (_, cu_id) in first_dones.items(): total_ms = 0 for comp_idx in range(8): cur.execute(f""" SELECT COALESCE(SUM(interval_time), 0) FROM bi_user_component_play_record_{comp_idx} WHERE chapter_unique_id = %s """, (cu_id,)) total_ms += cur.fetchone()[0] or 0 total_times.append(total_ms) avg_min = sum(total_times) / len(total_times) / 60000.0 results.append((season, unit, lesson, cid, len(total_times), round(avg_min, 1))) print(f" {season} {unit} {lesson} (id={cid}): {len(total_times)}人, 平均{round(avg_min, 1)}分钟") # 输出汇总 print("\n===== 汇总 =====") print(f"{'Season':<6} {'Unit':<6} {'Lesson':<8} {'ChapterID':<10} {'完成人数':<10} {'平均用时(分钟)':<15}") for r in results: print(f"{r[0]:<6} {r[1]:<6} {r[2]:<8} {r[3]:<10} {r[4]:<10} {r[5]:<15}") # 按单元汇总 from collections import defaultdict unit_stats = defaultdict(lambda: {"count": 0, "avg": 0.0, "lessons": 0}) for r in results: key = f"{r[0]}_{r[1]}" unit_stats[key]["count"] += r[4] unit_stats[key]["avg"] += r[5] unit_stats[key]["lessons"] += 1 print("\n===== 按单元汇总 =====") print(f"{'Unit':<10} {'完成人数(合计)':<15} {'平均用时(分钟)':<15}") for key, stats in sorted(unit_stats.items()): print(f"{key:<10} {stats['count']:<15} {round(stats['avg']/stats['lessons'], 1):<15}") cur.close() conn.close()