我正在为学校设计一个测试系统。表格就像这样
------------------------------------------------------------------------------
Student_id | Total Questions | Questions Attempted | Correct
------------------------------------------------------------------------------
36 | 60 | 42 | 20
19 | 60 | 38 | 32
119 | 60 | 37 | 31
现在,标记方案为+3
表示正确,-1
表示错误
错误问题的数量将计算为wrong = attempted - correct
问题
1)我想根据他们的等级给予学生一些积分,所以我想按照他们的分数i.e. score = 3 * correct - wrong
的递减顺序对表格进行排序。虽然,我也可以存储得分但由于它是冗余数据,我不想将它存储到表中。如何使用SQL查询对表进行排序。
2)当我将学生的成绩根据他们的成绩更新到表student
时,我从student_id
表中选择result
并更新{{1}表,即每个学生1个查询。这意味着如果有4000名学生参加考试,那么4000个查询! 。我可以改善情况(最小化查询)吗?
修改
问题2的学生模式
student
答案 0 :(得分:3)
您只需在排序
中指定所需内容即可select student_id,correct, attempted,field4,field5, (3 * correct - (attempted-correct)) as score
from students sort by score desc
是的,看看bulk update的sql,你可以准备查询并按10或100比100更新10,但不要太多,因为sql命令对其长度有限制
答案 1 :(得分:1)
问题1。
假设该表名为Results,并且该Student_id是唯一的,以下是您的问题的可能解决方案:
SELECT Results.*, (3*Correct-(Total_Questions-Correct)) AS score
FROM Results
ORDER BY score DESC
问题2。
假设学生已经添加到学生表中,或者他们已经有分数,这是一个可能的SQL查询来更新学生表而不进行4k查询:
UPDATE StudentsTable AS s
INNER JOIN PointsTable AS p
ON s.Student_id = p.Student_id
SET
s.Points = s.Points + (3 * p.Correct - (p.Questions_Attempted - p.Correct))
如果将来需要执行更多测试,可以向Points Table添加Test_ID列,然后在UPDATE查询中添加WHERE子句,以便只添加给定测试的分数。
<强>优化强>
您可以通过更改计算分数的方式来优化查询:
SELECT Results.*, (2*Correct-Total_Questions) AS score
FROM Results
ORDER BY score DESC
UPDATE StudentsTable AS s
INNER JOIN PointsTable AS p
ON s.Student_id = p.Student_id
SET
s.Points = s.Points + (2 * p.Correct - p.Questions_Attempted)
答案 2 :(得分:0)
按分数对学生进行排名
SELECT student_id,
(
SELECT 1 + COUNT(*)
FROM student_results
WHERE 3 * correct - (total - correct) >=
3 * r.correct - (r.total - r.correct)
AND student_id <> r.student_id
) rank
FROM student_results r
输出:
| STUDENT_ID | RANK | |------------|------| | 36 | 3 | | 19 | 1 | | 119 | 2 |
现在,您可以使用多表UPDATE
语法一次性更新学生点数,而不是使用更新查询数量来访问数据库。
UPDATE students s JOIN
(
SELECT student_id,
(
SELECT 1 + COUNT(*)
FROM student_results
WHERE 3 * correct - (total - correct) >=
3 * r.correct - (r.total - r.correct)
AND student_id <> r.student_id
) rank
FROM student_results r
) q
ON s.student_id = q.student_id
SET s.points = s.points +
CASE q.rank -- implement your logic of translating ranks to points here
WHEN 1 THEN 100
WHEN 2 THEN 50
WHEN 3 THEN 10
ELSE 0
END;
这是 SQLFiddle 演示