Получение не группы по выражению при использовании функции listagg

CREATE TABLE source_det (
    e_id       NUMBER(10),
    sys_name   VARCHAR2(20),
    ref_id     NUMBER(10),
    sys_other  VARCHAR2(30)
);

INSERT INTO source_det VALUES(11,'SOURCE',992,null);
INSERT INTO source_det VALUES(11,'SOURCE',637,null);
INSERT INTO source_det VALUES(11,'SOURCE',null,'Manual');
INSERT INTO source_det VALUES(11,'TARGET',637,null);

commit;

Моя попытка:

SELECT e_id,
       LISTAGG(source, ';') source,
       LISTAGG(target, ';') target,
       source_other
  FROM (SELECT e_id,
               CASE
                 WHEN sys_name = 'SOURCE' THEN
                  ref_id
               END source,
               CASE
                 WHEN sys_name = 'TARGET' THEN
                  ref_id
               END target,
               CASE
                 WHEN sys_name = 'SOURCE' AND ref_id IS NULL THEN
                  sys_other
               END source_other
          FROM source_det
         GROUP BY e_id);

Из приведенного выше набора данных мне нужна только одна строка, которая должна быть возвращена из запроса SELECT, но вместо этого я получаю значения null вместе с требуемыми значениями. Если sys_name является ИСТОЧНИКОМ, то результат должен быть ref_id. Если имеется более одной записи, то она должна быть разделена разделителем; Если sys_name ЦЕЛЬ, то результат должен быть ref_id Если sys_name является ИСТОЧНИКОМ, а ref_id равно нулю, то в результате должно получиться sys_other. Но из моего запроса я не получаю ни одной строки, а получаю 4 строки. Но в идеале мне нужен только один ряд с e_id 11 И самое главное, вместо нулевых значений может быть () вместо нулевого. Значит, надо исключить и это. После получения желаемого результата мы можем использовать DECODE(ref_id,'()',null) следующим образом.

Ожидаемый результат:

e_idисточникцельисточник_другое
11992;637637Руководство по эксплуатации

Используемый инструмент: SQL Developer (18c)

Все столбцы в вашем операторе SELECT должны быть частью агрегатной функции (например, LISTAGG) или включены в предложение GROUP BY. У вас есть неагрегированные столбцы, такие как e_id, но нет предложения GROUP BY.

NickW 21.03.2022 17:39
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
1
27
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вам не нужен подзапрос, просто используйте его, как показано ниже.

SELECT e_id,
       LISTAGG(CASE
                 WHEN sys_name = 'SOURCE' THEN
                  ref_id
               END,
               ';') WITHIN GROUP(ORDER BY ref_id DESC) AS source,
       LISTAGG(CASE
                 WHEN sys_name = 'TARGET' THEN
                  ref_id
               END,
               ';') WITHIN GROUP(ORDER BY ref_id DESC) AS target,
       LISTAGG(CASE
                 WHEN sys_name = 'SOURCE' AND ref_id IS NULL THEN
                  DECODE(sys_other,'()','',sys_other)
               END,
               ';') WITHIN GROUP(ORDER BY 0) AS source_other
  FROM source_det
 GROUP BY e_id

где отсутствующий WITHIN GROUP (ORDER BY ..) должен следовать за выражением LISTAGG(...)

Demo

Спасибо за быстрый поворот. Это сработало для меня, но можем ли мы обработать () в нашем запросе, предположим, есть ли () вместо нуля в ref_id

Vicky 21.03.2022 18:03

Привет @Vicky, пожалуйста. Вы имеете в виду это..?

Barbaros Özhan 21.03.2022 18:19

Да. Спасибо за это. И еще одно, как вы добавили демонстрационную кнопку скрипки в свой ответ ??

Vicky 21.03.2022 18:24

@Vicky, извините меня, что я недавно понял для кнопки «Демо», где я использую <kbd>[Demo](thelink)</kbd>

Barbaros Özhan 22.03.2022 19:42

Другие вопросы по теме