0

我很抱歉,但标题有点误导。说我有以下表格

-- user_tests 表
姓名 | 类型
------------------------------------|----
编号 | 整数(11)
用户 ID | 整数(11)
test_schedule_id | 整数(11)
device_user_test_id | varchar(255)
time_take | 整数(11)
总分 | 整数(11)
总问题 | 整数(11)
尝试计数 | 整数(11)
created_at | 约会时间
更新时间 | 约会时间
-- user_test_questions 表
姓名 | 类型
------------|-------------
编号 | 整数
user_test_id | 整数
time_take | 整数
获得标记 | 整数
问题ID | 整数
是正确的| 枚举
test_section_id | 整数
created_at | 约会时间
更新时间 | 约会时间

表中的数据user_tests是参加了由 标识的特定考试的学生列表test_schedule_id。每一个test_schedule_id,都有一个或多个test_section_id

我正在尝试根据以下条件计算学生的排名:

  1. 根据学生的总成绩获得排名test_schedule_id
  2. 如果前一个案例的排名相同,则获得排名test_section_id= 1
  3. 如果前一个案例的排名相同,则获得排名test_section_id= 2
  4. 如果前一个案例的排名相同,则获得排名test_section_id= 3
  5. 如果前一个案例的排名相同,则获取用户表中用户出生日期的排名

我可以在 Rails(或任何框架)中轻松完成它们,但我想避免它并在 SQL 中使用 aView或 a来解决它Stored Procedure

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

谢谢

编辑:排名基于表中的total_marks任何一个。user_testsSUM(marks_obtained)user_test_questions

4

1 回答 1

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 与布尔值(test_section_id=1) 相乘,对于test_section_id = 1 的行,它将为1,而对于其他部分,则为0,依此类推。

在 GROUP BY 中,您会看到三列符合 sql 标准,但您也可以尝试只查看 utq.user_test_id ,因为其他列在每个组中具有相同的值。

对于 test_schedule_id 具有高度选择性的条件(您应该显然将其编入索引)并且参加每个测试的学生不多(最多可能有数百人),因此该查询应该是即时的,因为所有排序都将在一个非常小的临时表上完成。

于 2013-06-14T06:56:30.073 回答