我很抱歉,但标题有点误导。假设我有以下表格
-- user_tests table Name | Type ------------------------|---------------- id | int(11) user_id | int(11) test_schedule_id | int(11) device_user_test_id | varchar(255) time_taken | int(11) total_marks | int(11) total_questions | int(11) attempt_count | int(11) created_at | datetime updated_at | datetime
-- user_test_questions table Name | Type ------------------------|------------- id | int user_test_id | int time_taken | int marks_obtained | int question_id | int is_correct | enum test_section_id | int created_at | datetime updated_at | datetime
user_tests
表中的数据是参加test_schedule_id
确定的特定考试的学生列表。每个test_schedule_id
都有一个或多个test_section_id
。
我正在尝试按以下条件计算学生的等级:
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
的{{1}}表中的SUM(marks_obtained)
排名。
答案 0 :(得分:1)
让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_obtained与boolean(test_section_id = 1)相乘,对于test_section_id = 1的行为1,对于其他部分为0,依此类推。
在GROUP BY中,您会看到三列符合sql标准,但您也可以尝试在那里看到utq.user_test_id,因为其他列在每个组中都具有相同的值。
对于test_schedule_id具有高度选择性的条件(你应该明确索引它)并且参加每个测试的学生不多(最多可能是数百个),这个查询应该是即时的,因为所有的排序都将在一个非常小的临时表上完成。 / p>