抱歉,标题有点误导。说我有下表
-user_tests表
姓名|类型
------------------------ | ----------------
id |整数(11)
user_id |整数(11)
test_schedule_id |整数(11)
device_user_test_id | varchar(255)
耗时|整数(11)
total_marks |整数(11)
total_questions |整数(11)
try_count |整数(11)
created_at |约会时间
Updated_at |约会时间
-user_test_questions表
姓名|类型
------------------------ | -------------
id |整型
user_test_id |整型
耗时|整型
标记|整型
问题ID |整型
is_correct |枚举
test_section_id |整型
created_at |约会时间
Updated_at |约会时间user_tests
表中的数据是已通过test_schedule_id
标识的特定考试的学生列表。每个test_schedule_id
具有一个或多个test_section_id
。
我正在尝试在以下条件下计算学生排名:
根据学生的Total_Marks获得test_schedule_id
的排名
如果先前案例的等级相同,则在test_section_id
= 1上获得等级
如果先前案例的等级相同,则在test_section_id
= 2上获得等级
如果先前案例的等级相同,则在test_section_id
= 3上获得等级
如果先前案例的等级相同,则在用户表中获取用户的出生日期等级
我可以在Rails(或任何框架)中轻松地实现它们,但是我想避免这样做,而使用View
或Stored Procedure
在SQL中解决它。
现在,我知道了如何分别计算排名,但是我正在努力结合这些条件。有没有办法做到这一点?我想我只是缺少MS SQL Server Rank()函数!
谢谢
编辑:基于total_marks
表中user_tests
的SUM(marks_obtained)
表中的user_test_questions
进行排名。
最佳答案
让mysql完成其工作是一个好主意-所有联接和排序类型的东西。
我会喜欢的东西:
SELECT u.id AS uid,
SUM( utq.marks_obtained ) AS total_marks,
SUM( (utq.test_section_id = 1)*utq.marks_obtained ) AS section1_marks,
SUM( (utq.test_section_id = 2)*utq.marks_obtained ) AS section2_marks,
SUM( (utq.test_section_id = 3)*utq.marks_obtained ) AS section3_marks,
u.birthdate
FROM user_test_questions utq
JOIN user_tests ut ON ut.id = utq.user_test_id
JOIN users u ON u.id = ut.user_id
WHERE ut.test_schedule_id = 1
GROUP BY utq.user_test_id, u.id, u.birthdate
ORDER BY total_marks DESC, section1_marks DESC, section2_marks DESC, section3_marks DESC, u.birthdate
计算每个部分的标记的技巧是将marks_ob获得的值与布尔值(test_section_id = 1)相乘,对于具有test_section_id = 1的行,该值将为1;对于其他部分,该值为0,依此类推。
在GROUP BY中,您看到符合SQL标准的三列,但您也可以尝试在其中仅查看utq.user_test_id,因为其他列在每个组中具有相同的值。
由于对test_schedule_id具有高度选择性的条件(您应该为它建立索引),并且参加每个测试的学生并不多(最多可能为数百名),因此该查询应该是即时的,因为所有排序都将在一个非常小的临时表上进行。
关于mysql - MySQL-计算多个条件下的学生排名,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17101679/