MySQL-计算学生在多种条件下的排名

MySQL-计算学生在多种条件下的排名,mysql,Mysql,对不起,这个标题有点误导人。假设我有下列表格 -- user_tests table Name | Type ------------------------|---------------- id | int(11) user_id | int(11) test_schedule_id | int(11) device_user_test_id

对不起,这个标题有点误导人。假设我有下列表格

-- 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 --用户测试表 名称|类型 ------------------------|---------------- id | int(11) 用户id| int(11) 测试计划表id内(11) 设备用户测试id varchar(255) 所用时间| int(11) 总分|整数(11) 总问题数(11) 尝试计数|整数(11) 在|日期时间创建|u 在|日期时间更新|U --用户\测试\问题表 名称|类型 ------------------------|------------- id | int 用户测试id int 所用时间| int 获得的分数| int 问题| id | int |枚举是否正确 测试_段_id | int 在|日期时间创建|u 在|日期时间更新|U
user\u tests
表中的数据是参加了由
test\u schedule\u id
确定的特定考试的学生列表。每个
测试计划\u id
,都有一个或多个
测试部分\u id

我试图在以下条件下计算学生的排名:

  • 根据学生在
    考试时间表\u id
  • 如果前一个案例的排名相同,则在
    测试部分\u id
    =1上获得排名
  • 如果前一个案例的排名相同,则在
    测试部分\u id
    =2上获得排名
  • 如果前一个案例的排名相同,则在
    测试部分\u id
    =3上获得排名
  • 若前一个案例的排名相同,则获取用户表中用户出生日期的排名
  • 我可以在Rails(或任何框架)中轻松地完成它们,但我希望避免它,并使用SQL中的
    视图
    存储过程
    来解决它

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

    多谢各位


    编辑:根据
    user\u tests中的
    total\u marks
    表中的
    SUM(获得的分数)
    user\u tests\u 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
    
    计算每个部分的标记数的技巧是将用布尔值(test_section_id=1)获得的标记_相乘,对于test_section_id=1的行,该值为1,对于其他部分,该值为0,依此类推

    在GroupBy中,您可以看到符合sql标准的三列,但您也可以尝试在其中只看到utq.user\u test\u id,因为其他列在每个组中具有相同的值


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

    rails向您显示它在运行日志中执行的SQL,如果内存可用,为什么不编写一个rails应用程序来看看它会产生什么,并使用这些查询呢?@hd1,这将是单独的查询,在很多方面,我会使用数组或哈希来组合它们。所以,我只是猜测它可能不起作用。你有没有尝试过,或者你只是打算直接放弃它?@hd1,我没有放弃这个想法。我试着离开了它,因为它只生成了一条语句,对于为完整的MySQL解决方案编写相关的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