描述
現有試卷作答記錄表exam_record(uid用戶ID, exam_id試卷ID, start_time開始作答時間, submit_time交卷時間, score得分):
id | uid | exam_id | start_time | submit_time | score |
1 | 1001 | 9001 | 2021-09-01 09:01:01 | 2021-09-01 09:41:01 | 81 |
2 | 1002 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 70 |
3 | 1002 | 9001 | 2021-09-01 19:01:01 | 2021-09-01 19:40:01 | 80 |
4 | 1002 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 70 |
5 | 1004 | 9001 | 2021-09-01 19:01:01 | 2021-09-01 19:40:01 | 85 |
6 | 1002 | 9002 | 2021-09-01 12:01:01 | (NULL) | (NULL) |
題目練習表practice_record(uid用戶ID, question_id題目ID, submit_time提交時間, score得分):
id | uid | question_id | submit_time | score |
1 | 1001 | 8001 | 2021-08-02 11:41:01 | 60 |
2 | 1002 | 8001 | 2021-09-02 19:30:01 | 50 |
3 | 1002 | 8001 | 2021-09-02 19:20:01 | 70 |
4 | 1002 | 8002 | 2021-09-02 19:38:01 | 70 |
5 | 1003 | 8001 | 2021-08-02 19:38:01 | 70 |
6 | 1003 | 8001 | 2021-08-02 19:48:01 | 90 |
7 | 1003 | 8002 | 2021-08-01 19:38:01 | 80 |
請統計每個題目和每份試卷被作答的人數和次數,分別按照"試卷"和"題目"的uv & pv降序顯示,示例數據結果輸出如下:
tid | uv | pv |
9001 | 3 | 3 |
9002 | 1 | 3 |
8001 | 3 | 5 |
8002 | 2 | 2 |
解釋:“試卷”有3人共練習3次試卷9001,1人作答3次9002;“刷題”有3人刷5次8001,有2人刷2次8002
SELECTexam_id AS tid,COUNT(DISTINCT exam_record.uid) uv,COUNT(*) pv
FROMexam_record
GROUP BYexam_id
UNION
SELECTquestion_id AS tid,COUNT(DISTINCT practice_record.uid) uv,COUNT(*) pv
FROMpractice_record
GROUP BYquestion_id
ORDER BYLEFT(tid, 1) DESC,uv DESC,pv DESC;
🔍 分步拆解與核心知識點
🧱 第一部分:考試行為統計(Exam UV/PV)
SELECTexam_id AS tid,COUNT(DISTINCT uid) AS uv,COUNT(*) AS pv
FROM exam_record
GROUP BY exam_id
字段 | 說明 |
---|---|
exam_id AS tid | 統一別名為?tid (目標 ID),便于合并 |
COUNT(DISTINCT uid) | 計算該試卷的獨立用戶數(UV) |
COUNT(*) | 總作答次數(PV) |
GROUP BY exam_id | 按試卷分組統計 |
🧱 第二部分:練習行為統計(Question UV/PV)
SELECTquestion_id AS tid,COUNT(DISTINCT uid) AS uv,COUNT(*) AS pv
FROM practice_record
GROUP BY question_id
結構與第一部分完全一致,只是數據源不同。
🧱 合并:UNION
-- 第一個查詢
...
UNION
-- 第二個查詢
- ??
UNION
?將兩個結構相同的查詢結果縱向拼接 - 要求:各列類型和順序必須一致(這里都是?
tid
,?uv
,?pv
) - 自動去重(如用?
UNION ALL
?則不去重)
🧱 排序:ORDER BY LEFT(tid, 1) DESC, uv DESC, pv DESC
ORDER BYLEFT(tid, 1) DESC, -- 按 tid 的第一個字符降序uv DESC,pv DESC