我有一个基于学生观看视频的学习系统,然后回答这些视频附带的问题。 (简化)模型基本上是这样的:
课程(课程定义,例如基础代数)
----------------------------------------
| id | int | auto_increment | PK |
| name | varchar | | |
----------------------------------------
课程实例(当用户开始课程时,此处会记录一个条目)
---------------------------------------------
| id | int | auto_increment | PK |
| course_id | int | | FK |
---------------------------------------------
视频(与特定课程相关)
---------------------------------------------
| id | int | auto_increment | PK |
| course_id | int | | FK |
| name | varchar | | |
---------------------------------------------
问题(与给定视频相关)
--------------------------------------------
| id | int | auto_increment | PK |
| video_id | int | | FK |
| q_text | varchar | | |
--------------------------------------------
我想要的是是获取所有课程实例和每个视频的问题数量,以逗号分隔。
例如,如果一门课程附有三个视频,第一个视频有两个问题,第二个和第三个视频各有一个问题,我想要这个:
-----------------------------------
| course_instance_id | qs_per_vid |
-----------------------------------
| 1 | 3,2,2 |
-----------------------------------
我从自己的努力中得到的最好的就是:
SELECT
ci.id,
COUNT(DISTINCT videos.id) AS num_vids,
GROUP_CONCAT(questions.video_id ORDER BY questions.video_id) AS questions
FROM course_instances ci
LEFT JOIN videos ON videos.course_id = ci.course_id
LEFT JOIN questions ON questions.video_id = videos.id
GROUP BY ci.id
产生类似的东西:
---------------------------------
| id | num_vids | questions | <-- actually it's the vid ID of each question
---------------------------------
| 1 | 4 | 1,1,1,2,2,3,3 |
---------------------------------
...我可以通过重复的视频ID序列推断出第一个视频有三个问题,第二个和第三个有问题。
但我怎样才能最终得到我想要的输出?
答案 0 :(得分:2)
你需要聚合两次。一种方法是在执行join
:
SELECT ci.id,
COUNT(v.id) AS num_vids,
GROUP_CONCAT(q.numquestions ORDER BY q.video_id) AS questions
FROM course_instances ci LEFT JOIN
videos v
ON v.course_id = ci.course_id LEFT JOIN
(SELECT q.video_id, COUNT(*) as numquestions
FROM questions q
GROUP BY q.video_id
) q
ON q.video_id = v.id
GROUP BY ci.id;
子查询计算每个视频的问题数。然后外部查询将这些连接在一起成为您想要的结果字符串。