Как напечатать различный вывод в LISTAGG () в зависимости от количества агрегированных элементов?
Можно ли получить количество агрегированных элементов без дополнительного запроса COUNT (*)?
Есть пример DDL:
create table shepherds (
SHEPHERD_ID NUMBER(19),
SHEPHERD_NAME VARCHAR2(50 CHAR)
);
create table sheeps (
SHEEP_ID VARCHAR2(10 CHAR),
SHEEP_NAME VARCHAR2(50 CHAR),
SHEEP_SHEPHERD_ID NUMBER(19)
);
-- insert shepherds
insert into shepherds VALUES (111, 'Asher');
insert into shepherds VALUES (222, 'Joseph');
insert into shepherds VALUES (333, 'Nicodemus');
-- first shepherd (one sheep)
insert into sheeps VALUES ('A', 'Mark', 111);
-- second shepherd (two sheeps)
insert into sheeps VALUES ('A', 'Andres', 222);
insert into sheeps VALUES ('B', 'Jeffrey', 222);
-- third shepherd (three sheeps)
insert into sheeps VALUES ('B', 'Jeffrey', 333);
insert into sheeps VALUES ('A', 'Andres', 333);
insert into sheeps VALUES ('D', 'Andres', 333);
Теперь я хочу отобразить всех пастухов с разделенными новой строкой именами овец следующим образом:
SELECT
SHEPHERD_NAME,
(SELECT
listagg(SHEEP_ID || ': ' || SHEEP_NAME, CHR(10)) WITHIN GROUP (ORDER BY SHEEP_ID)
FROM SHEEPS
WHERE SHEEP_SHEPHERD_ID = SHEPHERD_ID)
FROM SHEPHERDS;
Результат: http://sqlfiddle.com/#! 4 / 881a7 / 3
Однако я хочу скрыть овечье удостоверение личности для тех пастухов, у которых есть только одна овца.
Я попробовал следующее:
SELECT
SHEPHERD_NAME,
(SELECT
listagg(
CASE WHEN COUNT(*) > 1 THEN SHEEP_ID || ': ' ELSE '' END
|| SHEEP_NAME, CHR(10)) WITHIN GROUP (ORDER BY SHEEP_ID)
FROM SHEEPS
WHERE SHEEP_SHEPHERD_ID = SHEPHERD_ID)
FROM SHEPHERDS;
Однако я получаю сообщение об ошибке:
ORA-00978: функция вложенной группы без GROUP BY
http://sqlfiddle.com/#! 4 / 881a7 / 7
Можно ли вернуть другую строку из LISTAGG (), если агрегируется только один элемент?
Как определить количество агрегированных элементов без снижения производительности запросов в Oracle 11 г или выше?