通过最新日期Oracle进行联接的聚合函数

时间:2019-09-12 15:55:17

标签: oracle date join aggregate greatest-n-per-group

我正在尝试通过考试类型,考试要素,学期和ID为学生选择一个考试分数。每个ID一分。如果一个学生多次参加考试,我只想返回该考试和元素的最高(或最新)分数。

我的问题是,在极少数情况下(2000年少于10条记录),学生在不同的日期记录了两个考试成绩,因为他们重新参加考试以提高成绩,我们记录两个分数。因此,我的输出具有少量记录,这些记录具有唯一的name_id(其中test_id ='act'和element_id ='comp')的多个分数。

两个表的示例是:

students
----------------------------------------------------------
name_id     term_id

100         Fall
100         Spring
100         Summer
105         Fall
105         Spring
110         Fall
110         Spring
110         Summer

test_score
----------------------------------------------------------
name_id     test_id   element_id    score         test_date

100         act       comp          25            02/01/2019
100         sat       comp          1250          01/20/2019
105         act       comp          19            01/15/2019
105         act       comp          21            02/28/2019
110         act       comp          27            01/31/2019      

我尝试使用MAX(test_score),但也许可以使用MAX(test_date)?这两种方法都是可行的,因为如果分数不高于最初报告的分数,则学生以后不会再报告其他分数。

这是连接多个表的较大例程的一小部分,因此我不知道可以替换我的JOIN。我只是想让例程的一小部分产生正确数量的唯一记录

SELECT
       a.name_id NameID,
       a.term_id TermID,
       MAX(b.score) Score

       FROM students a

       LEFT JOIN test_score b ON a.name_id = b.name_id AND b.test_id = 'act' AND b.element_id = 'comp'

     WHERE a.term_id = 'Spring'

     group by b.score,a.name_id,a.term_id
     order by a.name_id

没有错误消息,但是从上面得到的结果将为NameID 105产生两条记录:

NameID    TermID    Score
100       Spring    25
105       Spring    19
105       Spring    21
110       Spring    27

我不确定如何编写此代码以仅选择最高分数(或仅选择最近日期的分数)

感谢您的指导。

1 个答案:

答案 0 :(得分:1)

要选择最高分数,GROUP BY不能包含该分数...

SELECT
       a.name_id NameID,
       a.term_id TermID,
      MAX(b.score) Score

       FROM students a

       LEFT JOIN test_score b ON a.name_id = b.name_id AND b.test_id = 'act' AND b.element_id = 'comp'

    WHERE a.term_id = 'Spring'

     group by a.name_id,a.term_id
     order by a.name_id

要获取与最高日期相关的分数...

SELECT x.NameID,
       x.TermID,
       y.score
FROM (
SELECT
       a.name_id NameID,
       a.term_id TermID,
   ---  MAX(b.score) Score
       MAX(b.test_date) test_date

       FROM students a

       LEFT JOIN test_score b ON a.name_id = b.name_id AND b.test_id = 'act' AND b.element_id = 'comp'

    WHERE a.term_id = 'Spring'

     group by a.name_id,a.term_id ) x

     LEFT JOIN test_score y ON x.nameid = y.name_id AND x.test_date = y.test_date
     order by x.nameid