выполнение вычислений с данными табличного типа

#oracle #plsql

#Oracle #plsql

Вопрос:

  1. создан тип записи — trec
  2. Затем создана таблица v1 с указанным выше типом записи abc
  3. используя курсор, загруженный студент, курс, оценивает данные из нескольких таблиц в таблицу типа v1 с помощью выборки и цикла.
  4. теперь я хотел бы рассчитать средний балл конкретного из версии v1.

может ли кто-нибудь предложить, как выполнить среднюю операцию с данными, существующими в t_tab

 set serveroutput on;
declare 
    type t_rec is record
    (
      student_id number,
      course_id number,
      grade number
    );
    error_msg varchar2(50);
    type abc is table of t_rec index by binary_integer;
    v1 abc;
    x number;
    cursor st_gr
    is 
      with sf as
      (
        select s.student_id as student_id, count(cr.course_id)as no_of_courses
        from grade g, student s, class cs, course cr
        where g.student_id = s.student_id
        and cs.course_id = cr.course_id
        and g.class_id = cs.class_id
        group by s.student_id
      )
      select x.student_id as student_id, cr.course_id as course_id, g.score as grade
      from sf x, grade g, class cs, course cr
      where x.no_of_courses>4 
      and x.student_id = g.student_id 
      and cs.course_id = cr.course_id
      and g.class_id = cs.class_id;

      i binary_integer :=0;
      temp binary_integer :=0;
begin
      open st_gr;
      loop
        i:=i 1;
        fetch st_gr into v1(i);
        exit when st_gr%notfound;
      end loop;
      close st_gr;
        dbms_output.put_line('students who enrolled in more than 4 courses');  
        dbms_output.put_line('student_id'||'    '||'course_id'||'          '||'grade');  
      select student_id, avg(grade)
      from v1
      group by student_id;
end;    
  

пожалуйста, дайте мне знать, если вопрос неясен

Ответ №1:

Есть ли причина не выбирать его в вашем запросе?

 select x.student_id as student_id, cr.course_id as course_i
     , g.score as grade, AVG(g.score) OVER (PARTITION BY x.student_id) as avg_score
 from sf x, grade g, class cs, course cr
where x.no_of_courses>4 
  and x.student_id = g.student_id 
  and cs.course_id = cr.course_id
  and g.class_id = cs.class_id;
  

Это добавит новое поле в вашу запись с именем avg_score со средним баллом для данного учащегося.

РЕДАКТИРОВАТЬ: В качестве альтернативы вы можете создать объявление ТИПА на уровне базы данных для структуры записей. Если вы хотите использовать DML для типа объекта, вам придется создавать его на уровне базы данных, а не на уровне PL / SQL, поскольку база данных не знает о типах, определенных в PL / SQL.

 CREATE OR REPLACE TYPE t_rec AS OBJECT
(
  student_id number,
  course_id number,
  grade number
);

CREATE OR REPLACE TYPE abc AS TABLE OF t_rec;
  

Затем в вашем коде:

 FOR Rec IN (SELECT student_id, AVG(grade) avg_grade 
              FROM TABLE ( cast( v1 as abc) )
             GROUP BY student_id) 
LOOP
   dbms_output.put_line(Rec.student_id, Rec.avg_grade);
END LOOP;
  

Полностью непроверенный. Тем не менее, это общая идея.

Комментарии:

1. я получу 5 записей, потому что студенты записываются на 5 курсов. я должен получить только одну запись .. на одного учащегося.

2. Сначала я должен отобразить набор курсов и их оценки для каждого учащегося, затем я должен вычислить среднее значение оценок для каждого учащегося, которое будет отображаться в виде одной записи.

3. Верно, но каждая из этих 5 записей будет иметь одинаковое среднее значение для учащегося. Используйте первую, последнюю или любую из многих записей, которые вы получаете для учащегося, чтобы получить их среднее значение.

4. Я добавил альтернативу своему ответу.