我正在尝试通过测试列出学生及其效率。
在MySql
数据库中我有表
users
- 与学生同桌
id | name
_________
1 | Joe
2 | Marry
3 | Max
4 | Anna
----------
courses
- 包含课程的表
id | name
_____________
1 | Course 1
2 | Course 2
----------
questions
- 每个课程都有问题的表格。 Row cours_id表示该问题属于哪个课程
id | cours_id | question
_________________________________
1 | 1 | Course 1 - question 1
2 | 1 | Course 1 - question 2
3 | 1 | Course 1 - question 3
4 | 1 | Course 1 - question 4
5 | 2 | Course 2 - question 1
6 | 2 | Course 2 - question 2
7 | 2 | Course 2 - question 3
8 | 2 | Course 2 - question 4
cours_invitations
- 每个学生都会收到课程邀请。行user_id显示被邀请进行课程的用户的ID。
cours_id代表学生应该做的课程的ID。
当行状态值为0表示学生没有开始课程(待定),如果它的值为1表示学生已经开始(或已完成)。
id | user_id | cours_id | status
________________________________
1 | 1 | 1 | 1
2 | 1 | 2 | 0
3 | 2 | 1 | 0
4 | 3 | 1 | 1
5 | 4 | 1 | 1
6 | 4 | 2 | 1
示例: Joe和Anna被邀请参加课程1和课程2,Marry和Max被邀请只参加课程1. Joe做了课程1而不是课程2,Marry没有做任何事情和马克斯都做了课程1
courses_stats
- 是学生们所做的课程问题的统计数据。状态代表答案的准确性。 0代表错误答案,1代表正确。
id | user_id | question_id | status
___________________________________
1 | 1 | 1 | 1
2 | 1 | 2 | 1
3 | 1 | 3 | 0
4 | 2 | 1 | 1
5 | 2 | 2 | 1
6 | 2 | 3 | 1
7 | 2 | 4 | 1
8 | 4 | 1 | 1
9 | 4 | 2 | 1
10 | 4 | 3 | 0
11 | 4 | 4 | 0
12 | 4 | 5 | 1
13 | 4 | 6 | 1
示例: Joe在第一期课程中提出了3个问题。通知他没有完成该课程的所有问题而且该课程不正确。
Max确实所有的问题都是正确的,Anna在第一道菜上做了所有问题(一半是不正确的),一半来自第二道菜(都是正确的)
我需要一个查询,包括名字,完成课程的百分比,他们所做的那些课程的正确答案的百分比(不是所有课程)以及按这些百分比命令学生的可能性。 像这样:
name | completed courses | completed questions
______________________________________________
Max |100% |100%
Anna |100% |50%
Joe |50% |50%
Marry |0% |0%
这样的事情是否可能?我是否需要在表中为此查询添加更多行?
答案 0 :(得分:4)
我认为这应该是你所需要的:
SELECT
users.name,
CONCAT(COUNT(
DISTINCT CASE
WHEN cours_invitations.status = 1 THEN
cours_invitations.id
ELSE
NULL
END
) / COUNT(
DISTINCT cours_invitations.id
) * 100, '%') AS completed_courses,
CONCAT(COUNT(
DISTINCT CASE
WHEN courses_stats.status = 1 THEN
courses_stats.id
ELSE
NULL
END
) / COUNT(DISTINCT questions.id) * 100, '%') AS completed_questions
FROM
users
LEFT JOIN cours_invitations ON cours_invitations.user_id = users.id
LEFT JOIN questions ON cours_invitations.cours_id = questions.cours_id
AND cours_invitations.status = 1
LEFT JOIN courses_stats ON users.id = courses_stats.user_id
GROUP BY
users.id
ORDER BY
completed_courses DESC,
completed_questions DESC
作为回答您的问题,为什么表名称为cours_*
而不是course_*
?
答案 1 :(得分:4)
在这里您可以找到表格模式和示例数据以及查询结果。 MichaelRushton有完美的答案,但我认为course_stats必须是LEFT join。 因为如果学生有cours_invitations但没有course_stats,那么该查询将不会返回该用户。
http://sqlfiddle.com/#!2/019dc/1
SELECT
users.name,
COUNT(
DISTINCT CASE
WHEN course_invitations.status = 1 THEN
course_invitations.id
ELSE
NULL
END
) / COUNT(
DISTINCT course_invitations.id
) * 100 AS completed_courses,
COUNT(
DISTINCT CASE
WHEN courses_stats.status = 1 THEN
courses_stats.id
ELSE
NULL
END
) / COUNT(DISTINCT questions.id) * 100 AS completed_questions
FROM users
INNER JOIN course_invitations ON course_invitations.user_id = users.id
INNER JOIN questions ON course_invitations.cours_id = questions.cours_id
LEFT JOIN courses_stats ON users.id = courses_stats.user_id
GROUP BY
users.id
<强>结果:强>
NAME COMPLETED_COURSES COMPLETED_QUESTIONS
Joe 50 25
Marry 0 100
Max 100 0
Anna 100 50
答案 2 :(得分:0)
我猜你的意思是“正确答案的百分比”。好的,通过巧妙地使用count(distinct if(..))
构造,您可以避免使用具有不同分组子句的复杂子查询。例如,此代码
count(distinct if(cours_invitations.status and courses_stats.status,
NULL, questions.id))
计算满足条件cours_invitations.status and courses_stats.status
的(不同)问题的数量。使用这个技巧,整个查询就像这样简单而优雅:
select users.name,
count(distinct if(cours_invitations.status,
NULL,
cours_invitations.cours_id))
/ count(distinct cours_invitations.cours_id)
* 100 as courses_completed,
count(distinct if(cours_invitations.status and courses_stats.status,
NULL,
questions.id))
/ count(distinct if(cours_invitations.status,
NULL,
questions.id))
* 100 as correct_answers
from users
left join cours_invitations on users.id = cours_invitations.user_id
left join questions using (cours_id)
left join courses_stats on users.id = courses_stats.user_id
and questions.id = courses_stats.question_id
group by users.id
order by correct_answers
我建议在mysql之外添加百分号,因为它在那里更加优雅,它会给mysql查询增加不必要的复杂性。