PL SQL: как получить более одного значения в одной ячейке?листаг, ок.Но - PullRequest
0 голосов
/ 03 января 2019

Я новичок в stackoverflow, поэтому, пожалуйста, извините, если я не правильно спрашиваю.

Я только что получил билет с просьбой изменить отчет.

Фактическая ситуация такова, что, когда сотрудник обучается на тренинге, в котором более одного сотрудника инструктора, записи дублируются столько же, сколько и количество инструкторов.

например. как следует


Stud_id | ins_fname | ins_lname


001 | Уго | красный


001 | Марко | зеленый

вместо этого должно быть


Stud_id | ins_fname | ins_lname


001 | Уго, Марко | красный, зеленый

Я знаю, что есть LISTAGG для решения этой проблемы, однако не работает должным образом.

Полагаю, поскольку значения stud_id извлекаются из вложенной таблицы, поэтому отчет, над которым я работаю, выглядит примерно так

ВЫБРАТЬ col_1, col_2, ins_fname, ins_lname, col_n + 1 ... п, ОТ (ВЫБЕРИТЕ DISTINCT stud.stud_id, col_n + 1 ... п, С таблицы ) tableName, tableName2, tableName3

ГДЕ 1 = 1

Есть ли вероятность, что это повлияет на функциональность LISTAGG?

Я получаю следующую ошибку

Столбец I.MI (который следует за столбцами, которые я пытаюсь выделить) недопустим в списке выбора, поскольку предложение GROUP BY или функция агрегации его не содержат: строка 26, столбец 7 (в позиции 1010) в de.simplicit.vjdbc.util.SQLExceptionHelper.wrapSQLException (SQLExceptionHelper.java:44) в de.simplicit.vjdbc.util.SQLExceptionHelper.wrap (SQLExceptionHelper.java:25) в de.simplicit.vjdbc.server.command.CommandProcessor.process (CommandProcessor.java:165) в de.simplicit.vjdbc.server.servlet.ServletCommandSink.handleRequest (ServletCommandSink.java:176) в de.simplicit.vjdbc.server.servlet.ServletCommandSink.doPost (ServletCommandSink.java:150) на javax.servlet.http.HttpServlet.service (HttpServlet.java:648) на javax.servlet.http.HttpServlet.service (HttpServlet.java:729) в org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.

Я знаю, что это не самый ясный вопрос, но я все равно буду признателен за любую поддержку.

Компилятор, который я использую - это Plateau Report Designer, построенный поверх BIRT, связанный с ORACLE db

Спасибо всем и с новым годом

1 Ответ

0 голосов
/ 03 января 2019

Мне кажется, я понял вашу проблему и она связана с группировкой!

Я потратил время на пересоздание вашего запроса, и это то, что я мог сделать, используя LiveSQL из Oracle

https://livesql.oracle.com/apex/livesql/s/hr0w91uigngd7wg5895ov7vc7

Если у вас нет доступа к Oracle, вы можете создать бесплатную учетную запись, но вот код, который я написал.

DROP TABLE training_instructor;
DROP TABLE training_enroll;
DROP TABLE employee;
DROP TABLE instructor;
DROP TABLE training;

CREATE TABLE employee(
  employee_id    NUMBER PRIMARY KEY
 ,employee_name  VARCHAR2(100)
);

CREATE TABLE instructor(
  instructor_id    NUMBER PRIMARY KEY
 ,instructor_name  VARCHAR2(100)
);

CREATE TABLE training(
  training_id    NUMBER   PRIMARY KEY
 ,training_name   VARCHAR2(100)
);

CREATE TABLE training_instructor(
  training_id    NUMBER
 ,instructor_id  NUMBER
 ,PRIMARY KEY(training_id, instructor_id)
);

CREATE TABLE training_enroll(
  training_id    NUMBER
 ,employee_id    NUMBER
 ,PRIMARY KEY(training_id, employee_id)
);

INSERT INTO employee VALUES(1,  'Employee 1');
INSERT INTO employee VALUES(2,  'Employee 2');
INSERT INTO employee VALUES(3,  'Employee 3');
INSERT INTO employee VALUES(4,  'Employee 4');
INSERT INTO employee VALUES(5,  'Employee 5');
INSERT INTO employee VALUES(6,  'Employee 6');
INSERT INTO employee VALUES(7,  'Employee 7');
INSERT INTO employee VALUES(8,  'Employee 8');
INSERT INTO employee VALUES(9,  'Employee 9');
INSERT INTO employee VALUES(10, 'Employee 10');
COMMIT;

INSERT INTO instructor VALUES(1, 'Instructor 1');
INSERT INTO instructor VALUES(2, 'Instructor 2');
INSERT INTO instructor VALUES(3, 'Instructor 3');
INSERT INTO instructor VALUES(4, 'Instructor 4');
INSERT INTO instructor VALUES(5, 'Instructor 5');
COMMIT;


INSERT INTO training VALUES(1, 'Training 1');
INSERT INTO training VALUES(2, 'Training 2');
INSERT INTO training VALUES(3, 'Training 3');
INSERT INTO training VALUES(4, 'Training 4');
INSERT INTO training VALUES(5, 'Training 5');
COMMIT;


INSERT INTO training_instructor VALUES(1, 1);
INSERT INTO training_instructor VALUES(2, 2);
INSERT INTO training_instructor VALUES(2, 3);
INSERT INTO training_instructor VALUES(3, 1);
INSERT INTO training_instructor VALUES(3, 3);
INSERT INTO training_instructor VALUES(3, 5);
INSERT INTO training_instructor VALUES(4, 2);
INSERT INTO training_instructor VALUES(4, 4);
INSERT INTO training_instructor VALUES(5, 4);
INSERT INTO training_instructor VALUES(5, 5);
COMMIT;


INSERT INTO training_enroll VALUES(1, 1);
INSERT INTO training_enroll VALUES(1, 2);
INSERT INTO training_enroll VALUES(1, 3);
INSERT INTO training_enroll VALUES(2, 6);
INSERT INTO training_enroll VALUES(2, 8);
INSERT INTO training_enroll VALUES(2, 10);
INSERT INTO training_enroll VALUES(2, 5);
INSERT INTO training_enroll VALUES(2, 4);
INSERT INTO training_enroll VALUES(3, 3);
INSERT INTO training_enroll VALUES(3, 5);
INSERT INTO training_enroll VALUES(3, 1);
INSERT INTO training_enroll VALUES(5, 10);
INSERT INTO training_enroll VALUES(5, 6);
COMMIT;
/
-- The final query
SELECT e.employee_id 
      ,e.employee_name 
      ,t.training_name 
      ,LISTAGG(i.instructor_name, ' | ')  WITHIN GROUP (ORDER BY i.instructor_name) instructor_list 
  FROM employee e 
       JOIN training_enroll te 
         ON e.employee_id = te.employee_id 
       JOIN training t 
         ON te.training_id = t.training_id 
       JOIN training_instructor ti 
         ON te.training_id = ti.training_id 
       JOIN instructor i 
         ON ti.instructor_id = i.instructor_id 
GROUP BY e.employee_id, e.employee_name, t.training_name 
ORDER BY e.employee_id, t.training_name 
...