抱歉,标题有点误导。说我有下表

-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(或任何框架)中轻松地实现它们,但是我想避免这样做,而使用ViewStored Procedure在SQL中解决它。

现在,我知道了如何分别计算排名,但是我正在努力结合这些条件。有没有办法做到这一点?我想我只是缺少MS SQL Server Rank()函数!

谢谢

编辑:基于total_marks表中user_testsSUM(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/

10-16 07:56