SQL MAX语句

时间:2016-01-24 05:38:14

标签: sql oracle top-n

我会更好地描述我的问题,并希望包含我的数据。

我有6张桌子需要的数据:

学生 StoredGrades sg 测试t TestScores ts StudentTest st StudentTestScore sts

这是我尝试做的事情。我需要一份能够运行的报告,它将向我展示学生最近在上学期获得的成绩以及他们HS职业生涯中最佳的PSAT考试成绩。

学生

ID  Student_Number  lastfirst   grade_level
1   1   Bird, Big   9
2   2   Bob, Sponge 10
3   3   Man, He 9
4   4   Rah, She    10
5   5   Myers, Michael  11

StoredGrades sg (我需要收集课程名称和编号以及教师姓名和收到的成绩)

course_name Course_number   Grade   Teacher_name    StudentID
Foundations of Catholic Worldview Honors    THE409  A+  Mr. M   1
US Government Honors    SOC405  A   Mrs. H  1
US Government Honors    SOC405  B-  Mr. H   1
Social Justice  THE404  A   Mrs. C  2
Psychology Honors   SOC605  A-  Mrs. E  2
Forensics   SCI334  A   Mrs. R  2
Social Justice  THE404  A+  Mr. H   3
US Government Honors    SOC405  B   Mrs. C  3
Peace and Justice I Honors  THE407  A+  Mrs. E  3
Peace and Justice I THE406  A-  Mrs. R  4
Peace and Justice I THE406  A+  Mrs. E  4
Economics Honors    SOC415  A-  Mrs. R  4
Peace and Justice I THE406  A-  Mr. H   4
US Government   SOC400  A+  Mr. L   5
Peace and Justice I Honors  THE407  A+  Mr. B   5
Social Justice Honors   THE405  A+  Mrs. C  5

测试分数来自4个表:

测试t (给我们表的名称)

ID  Name
3   PSAT

TestScores ts (给我们测试中需要的子分数)

ID  Name    TestID
51  PSAT_Critical Reading   3
53  PSAT_Math   3

StudentTest st (告诉我们学生考试的次数,考试的日期,以及学生参加考试的次数)

ID StudentID TestID Test_Date 658 1 3 12/1/2015 998 2 3 12/1/2015 100 2 3 12/1/2016 1354 3 3 12/1/2014 1500 3 3 12/1/2015 1688 3 3 12/1/2016 8875 4 3 12/1/2015 3364 5 3 12/1/2015

StudentTestScore sts (告诉我们学生如何在考试中得分。例如,Big Bird在他的批判性阅读PSAT测试中获得了78%。)

ID  NumScore    StudentID   StudentTestID   TestScoreID
573 78  1   658 51
574 65  1   658 53
385 62  2   998 51
387 68  2   998 53
889 89  2   100 51
892 92  2   100 53
112 58  3   1354    51
113 59  3   1354    53
6544    68  3   1688    51
6546    62  3   1688    53
8882    75  3   1500    51
8889    79  3   1500    53
425 98  4   8875    51
426 97  4   8875    53
658 82  5   3364    51
659 86  5   3364    53

这就是我想要的:

ID  Student_Number  lastfirst   grade_level Teacher_name    course_name Course_number   Grade   Test Date   Test Name   Best PSAT Reading Score Best PSAT Math Score
1   1   Bird, Big   9   Mr. M   Foundations of Catholic Worldview Honors    THE409  A+  12/1/2015   PSAT    78  65
1   1   Bird, Big   9   Mrs. H  US Government Honors    SOC405  A   12/1/2015   PSAT    78  65
1   1   Bird, Big   9   Mr. H   US Government Honors    SOC405  B-  12/1/2015   PSAT    78  65
2   2   Bob, Sponge 10  Mrs. C  Social Justice  THE404  A   12/1/2016   PSAT    89  92
2   2   Bob, Sponge 10  Mrs. E  Psychology Honors   SOC605  A-  12/1/2016   PSAT    89  92
2   2   Bob, Sponge 10  Mrs. R  Forensics   SCI334  A   12/1/2016   PSAT    89  92
3   3   Man, He 9   Mr. H   Social Justice  THE404  A+  12/1/2015   PSAT    75  79
3   3   Man, He 9   Mrs. C  US Government Honors    SOC405  B   12/1/2015   PSAT    75  79
3   3   Man, He 9   Mrs. E  Peace and Justice I Honors  THE407  A+  12/1/2015   PSAT    75  79
4   4   Rah, She    10  Mrs. R  Economics Honors    SOC415  A-  12/1/2015   PSAT    98  97
4   4   Rah, She    10  Mr. H   Peace and Justice I THE406  A-  12/1/2015   PSAT    98  97
5   5   Myers, Michael  11  Mr. L   US Government   SOC400  A+  12/1/2015   PSAT    82  86
5   5   Myers, Michael  11  Mr. B   Peace and Justice I Honors  THE407  A+  12/1/2015   PSAT    82  86
5   5   Myers, Michael  11  Mrs. C  Social Justice Honors   THE405  A+  12/1/2015   PSAT    82  86

我得到的是:

ID  Student_Number  lastfirst   grade_level Teacher_name    course_name Course_number   Grade   Test Date   Test Name   Best PSAT Reading Score Best PSAT Math Score
4   4   Rah, She    10  Mrs. R  Economics Honors    SOC415  A-  12/1/2015   PSAT    98  97
4   4   Rah, She    10  Mr. H   Peace and Justice I THE406  A-  12/1/2015   PSAT    98  97

它提取学生ID 4,因为他们拥有最好的测试结果。我需要每个人的个人最佳测试结果。

我感谢你能给我的任何帮助!

1 个答案:

答案 0 :(得分:0)

您尚未提供任何样本数据,因此以下是推断。

您的查询会返回许多无关的列,例如教师的姓名和课程,这意味着每个学生都会获得多行。

您的查询似乎包含参数化学生ID的连接,这可能是您只为一个学生获取行的原因。

此查询使用分析RANK()函数来确定每个学生和子测试的分数最高。

SELECT StuNumber
        , StuName
        , GradeLevel
        , test_name
        , MAX(CASE WHEN test_subtest ='PSAT_CriticalReading' THEN Num_Score ELSE null END) as ReadingTest
        , MAX(CASE WHEN test_subtest ='PSAT_Math' THEN Num_Score ELSE null END) as MathematicsTest 
FROM ( 
    SELECT s.Student_Number as StuNumber
           , s.lastfirst as StuName
           , s.Grade_Level as GradeLevel
            , t.name as Test_Name
            , ts.Name as Test_Subtest
            , sts.NumScore as Num_Score  
            , rank() over (partition by s.Student_Number, ts.Name order by sts.NumScore ) as score_rank
    FROM    Students s
    INNER JOIN StudentTest st ON s.ID = st.studentID  
    INNER JOIN StudentTestScore sts ON sts.StudentTestID = st.ID          
    INNER JOIN Test t ON st.TestID = t.ID  
    INNER JOIN TestScore ts ON ts.ID = sts.TestScoreID
    WHERE t.name = 'PSAT' 
    AND s.Enroll_Status=0 
    AND s.Grade_Level >=9 
    AND s.schoolid = ~(curschoolid) 
    ) TST 
AND score_rank = 1
GROUP BY StuNumber
          , StuName
          , GradeLevel
          , test_name

过滤rank = 1的子查询可防止包含其他分数。排除教师姓名和其他内容应该给每个学生一排。 "宜"因为在没有样本数据的情况下我无法对此进行测试。删除studentId上的过滤器意味着包含所有学生。

如果您有实际要求以返回问题中显示的更宽的结果集,则需要以不同的方式满足它。

顺便说一下,MAX(TO_CHAR(test_date,'MM/DD/YYYY'))并没有按照您的想法行事。将日期转换为字符串意味着排序使用ASCII值,因此12/31/2013高于01/01/2016。我们可以对Oracle日期进行算术运算:这会得到预期的结果:MAX(test_date)