SQL - 如何列出低于平均值的项目

时间:2014-02-22 15:57:06

标签: mysql sql

我有3个表的基本数据库。 “学生”“考试”和“分数”

对于每个测试,我需要列出所有测试成绩低于该测试平均值的学生。 (如果这有任何意义的话)

我有一个SQL查询,它只打印每个测试的平均分数。

SELECT t.Test_name, AVG(sc.Result) AS Avgscore
FROM Tests t 
JOIN Scores sc ON t.id_Tests = sc.Tests_id_Tests
JOIN Students s ON sc.Students_id_Students = s.id_Students
WHERE t.id_Tests = $c"

($ c是来自for循环的参数,递增为将每个测试作为单独的表打印出来)

感谢任何帮助,谢谢

2 个答案:

答案 0 :(得分:2)

更改您要显示的列的选择列表,但这会限制您想要的结果,对于给定的testid(将testXYZ替换为您正在搜索的实际测试)

SELECT t.Test_name, s.*, sc.*
  FROM Tests t
  JOIN Scores sc
    ON t.id_Tests = sc.Tests_id_Tests
  JOIN Students s
    ON sc.Students_id_Students = s.id_Students
 WHERE t.id_Tests = 'textXYZ'
   and sc.result <
       (select avg(x.result)
          from scores x
         where sc.Tests_id_Tests = x.Tests_id_Tests)

注意:要为所有测试运行此测试,并将分数限制在低于每个测试的平均值的分数,您只需将那一行留在where子句中并运行:

SELECT t.Test_name, s.*, sc.*
  FROM Tests t
  JOIN Scores sc
    ON t.id_Tests = sc.Tests_id_Tests
  JOIN Students s
    ON sc.Students_id_Students = s.id_Students
 WHERE sc.result <
       (select avg(x.result)
          from scores x
         where sc.Tests_id_Tests = x.Tests_id_Tests)

答案 1 :(得分:0)

例如在PostgreSQL中你可以使用类似AVG(Score) OVER (GROUP BY id_Tests)的窗口函数,但在MySQL中我建议使用子查询如下:

SELECT Scores.*, Students.*, t.Test_name, Avgscore
FROM Scores
JOIN Students ON sc.Students_id_Students = s.id_Students
JOIN 
    SELECT id_Tests, t.Test_name, AVG(sc.Result) AS Avgscore
    FROM Tests t 
    JOIN Scores sc ON t.id_Tests = sc.Tests_id_Tests
    -- WHERE id_Tests = $c
    GROUP BY id_Tests, t.Test_name
) avgsc ON Scores.Tests_id_Tests=avgsc.id_Tests
WHERE Scores.Result < Avgscore

请注意,如果学生多次低于平均分数,可以多次列出 - 可能是也可能不是您想要的。

我注释掉过滤测试的行,因为我想一次检索所有测试更容易,但是如果你坚持在应用程序级别上对一个测试进行过滤,那么你可以通过取消注释来过滤这里。