【问题标题】:returning most recent value for each of many different classes of data in one SQL query?在一个 SQL 查询中返回许多不同类别数据中的每一个的最新值?
【发布时间】:2011-01-04 05:11:29
【问题描述】:

现在我有一个查询,它返回多个“类”数据的 最大 值。我正在尝试找出要更改的内容,以便我的查询将返回以下每个不同类的最新 最近 值。

数据本身就是一个学生成绩的大表。一个学生可以有多个学期的成绩(由 pgf.finalgradename 字段捕获)。 大多数学生只需通过学生标识符和班级标识符加入即可返回正确的数据;但是,我试图解释学生放弃课程的一个部分并注册另一部分(同一课程的)的情况。出于我的目的,我们可以假设最近更新的成绩代表首选记录。

除了下面的字段之外,还有一个 pgf.lastgradeupdate 字段表示记录的更新日期。在英语中,我希望得到的是基于 pgf.lastgradeupdate 的最新行。鉴于此数据:

studentid course_number finalgradename 百分比 lastgradeupdate 100 M900 H1 70 01-OCT-10 100 M900 H1 90 20-OCT-10 100 M900 H2 85 01-JAN-11 100 M900 H3 88 06-FEB-11 100 M900 H4 89 07-JUN-11

我希望查询返回:

学生号 H1 H2 H3 H4 100 90 85 88 89

这是我所拥有的:

select cc.studentid, 
max(case when pgf.finalgradename='H1' then pgf.percent else null end) as H1,
max(case when pgf.finalgradename='H2' then pgf.percent else null end) as H2,
max(case when pgf.finalgradename='H3' then pgf.percent else null end) as H3,
max(case when pgf.finalgradename='H4' then pgf.percent else null end) as H4
from cc

left outer join sections sect on abs(cc.sectionid) = sect.id
left outer join courses on sect.course_number = courses.course_number
left outer join pgfinalgrades pgf on cc.studentid = pgf.studentid and abs(cc.sectionid) = pgf.sectionid

where abs(cc.termid) >= 2000 and cc.course_number = 'M900'
group by cc.studentid

我是否需要为每个“类”数据创建一个子查询?还是我需要做一堆自我连接?我在这里读到的其他问题似乎只是基于只需要考虑一个日期而不是几个日期的情况。 谢谢!

【问题讨论】:

    标签: sql oracle10g


    【解决方案1】:

    这与你想要的有多接近?

    create table your_data(
      studentid       number
     ,course_number   varchar2(4)
     ,finalgradename  varchar2(2)
     ,percent         number
     ,lastgradeupdate date
    );
    
    insert into your_data values(100, 'M900', 'H1', 70, date '2010-10-01');
    insert into your_data values(100, 'M900', 'H1', 90, date '2010-10-20');
    insert into your_data values(100, 'M900', 'H2', 85, date '2011-01-01');
    insert into your_data values(100, 'M900', 'H3', 88, date '2011-02-06');
    insert into your_data values(100, 'M900', 'H4', 89, date '2011-06-07');
    
    commit;
    
    
    select studentid
          ,course_number
          ,max(case when finalgradename = 'H1' then percent end) as h1
          ,max(case when finalgradename = 'H2' then percent end) as h2
          ,max(case when finalgradename = 'H3' then percent end) as h3
          ,max(case when finalgradename = 'H4' then percent end) as h4
      from (select studentid
                  ,finalgradename
                  ,course_number
                  ,percent
                  ,row_number() over(partition by studentid
                                                 ,course_number
                                                 ,finalgradename 
                                         order by lastgradeupdate desc) as rn
              from your_data
            )
     where rn = 1
     group 
        by studentid
          ,course_number;
    
     STUDENTID COUR         H1         H2         H3         H4
    ---------- ---- ---------- ---------- ---------- ----------
           100 M900         90         85         88         89
    

    更新的查询: 我在我的里面插入了你的查询。我无法测试它...如果它有效,请告诉我!

    select studentid
          ,course_number
          ,max(case when finalgradename = 'H1' then percent end) as h1
          ,max(case when finalgradename = 'H2' then percent end) as h2
          ,max(case when finalgradename = 'H3' then percent end) as h3
          ,max(case when finalgradename = 'H4' then percent end) as h4
      from (select cc.studentid
                  ,pgf.finalgradename
                  ,courses.course_number
                  ,pgf.percent
                  ,row_number() over(partition by cc.studentid
                                                 ,courses.course_number
                                                 ,pgf.finalgradename 
                                         order by lastgradeupdate desc) as rn
              from cc
        left outer 
              join sections sect     on abs(cc.sectionid) = sect.id
        left outer 
              join courses           on sect.course_number = courses.course_number
        left outer 
              join pgfinalgrades pgf on (cc.studentid = pgf.studentid and 
                                 abs(cc.sectionid) = pgf.sectionid)
             where abs(cc.termid) >= 2000 and cc.course_number = 'M900'
            )
     where rn = 1
     group 
        by studentid
          ,course_number;
    

    【讨论】:

    • 我应该指定的,对不起!不幸的是我不能写回数据——只能读取它。所以我不能使用依赖于创建另一个表的解决方案。
    • “your_data”是我没有您的表格的替代品:) 我假设您包含的查询(来自 cc、section、courses 等)产生了一个类似于示例数据的数据集。如果您使用我的查询,您可以将“your_data”替换为您自己的查询。
    • 明白了,谢谢——示例数据中的标题并不都位于一个表中——我将在您发布的代码中将联接放回哪里(部分/课程/等) ?
    • 就是这样!谢谢。我一定可以在其他地方回收利用 - 非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-01
    • 2014-09-15
    • 1970-01-01
    • 2015-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多