возвращать самое последнее значение для каждого из множества классов данных в одном запросе SQL? - PullRequest
0 голосов
/ 03 января 2011

Прямо сейчас у меня есть запрос, который возвращает значение наибольшее для нескольких «классов» данных. Я пытаюсь выяснить, что нужно изменить, чтобы мой запрос возвращал самое последнее значение для каждого из приведенных ниже классов.

Данные сами по себе представляют собой большую таблицу оценок учащихся. Студент может иметь оценки в нескольких терминах (фиксируется полем pgf.finalgradename). Для большинства учеников, просто соединяющихся по идентификатору ученика и идентификатору класса, вернут правильные данные; Тем не менее, я пытаюсь объяснить ситуации, когда студент оставляет один раздел курса и записывается в другой раздел (того же курса). Для моих целей мы можем предположить, что последняя обновленная оценка представляет предпочтительную запись.

В дополнение к полям ниже есть поле pgf.lastgradeupdate, которое представляет дату, когда запись была обновлена. В английском я надеюсь вернуться к самой последней строке, основанной на pgf.lastgradeupdate. Учитывая эти данные:

studentid     course_number     finalgradename     percent     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

Я бы хотел, чтобы запрос возвратил:

studentid     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

Нужно ли создавать подзапрос для каждого из этих «классов» данных? Или мне нужно сделать кучу самостоятельных соединений? Другие вопросы, которые я здесь читаю, казались основанными только на ситуациях, когда нужно было рассмотреть только одну дату, а не несколько. Спасибо!

1 Ответ

1 голос
/ 03 января 2011

Насколько это близко к тому, что вы хотите?

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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...