Почему я получаю ORA-00979 при попытке использовать LISTAGG и LEFT JOIN? - PullRequest
0 голосов
/ 15 февраля 2019

Я пытаюсь group мои результаты так, вместо того, чтобы выглядеть так:

id  | nome  |  bairro
---------------------
1 . |Test 1 | bairro 1
1 . |Test 1 | bairro 2
2 . |Test 2 | bairro 3

Это выглядит так:

id  | nome  |  bairro
----------------------
1 . |Test 1 | bairro 1, bairro 2
2 . |Test 2 | bairro 3

'id' и 'nome »в таблице 1, а« bairro »в table 3 в столбце« nome ».

таблица 1

id  | nome  | situacao
--------------------
1 . |Test 1 | EM_ATIVIDADE
2 . |Test 2 | EM_ATIVIDADE

таблица 2

id  | escola (fgk table 1) | bairro (fgk table 3)
-------------------------------------------------
1 . | 2                    | 1
2 . | 2                    | 2

таблица 3

id  | nome     
---------------
1 . | bairro 1 
2 . | bairro 2 

Я пытаюсь сделать это, используя LISTAGG с кодом ниже:

SELECT table1.nome, table1.id, LISTAGG(table3.nome, ', ') WITHIN GROUP (ORDER BY table3.nome) as "bairro"
FROM table1
LEFT JOIN table2 on table2.escola = table1.id
LEFT JOIN table3 on table3.id = table2.bairro
WHERE table1.situacao = 'EM_ATIVIDADE'
GROUP BY table1.id, table1.nome
ORDER BY table1.id

Когда я это делаю, я получаю сообщение об ошибке

ORA-00979: не группа по выражению

Может кто-нибудь мне помочь?Я новичок

edit : уже пытался добавить table1.nome в мою группу с помощью.

Ответы [ 2 ]

0 голосов
/ 15 февраля 2019

Я думаю, это потому, что вы используете функцию агрегирования, которая возвращает одну строку вместе со столбцами, которые будут возвращать несколько строк.Поэтому вам нужно либо сгруппировать каждый «нормальный» столбец в предложении GROUP BY, либо применить некоторую агрегирующую функцию к значениям из «нормальных» столбцов, например MIN, MAX, SUM и т. Д.

В вашемНапример, это будет что-то вроде

SELECT table1.nome, table1.id, LISTAGG(table2.nome, ', ') WITHIN GROUP (ORDER BY table2.nome) as "bairro"
FROM table1
LEFT JOIN table2 on table2.escola = table1.id
LEFT JOIN table3 on table3.id = table2.bairro
WHERE table1.situacao = 'EM_ATIVIDADE'
GROUP BY table1.nome, table1.id
ORDER BY table1.id

или

SELECT MAX(table1.nome), MAX(table1.id), LISTAGG(table2.nome, ', ') WITHIN GROUP (ORDER BY table2.nome) as "bairro"
FROM table1
LEFT JOIN table2 on table2.escola = table1.id
LEFT JOIN table3 on table3.id = table2.bairro
WHERE table1.situacao = 'EM_ATIVIDADE'
ORDER BY table1.id

Существует альтернатива, которая заключается в использовании предложения

OVER (partition BY <column name here>) 

, например что-то вроде

SELECT table1.nome, table1.id, LISTAGG(table3.nome, ', ') WITHIN GROUP (ORDER BY table3.nome) OVER (PARTITION BY table1.id) as "bairro"
FROM table1
LEFT JOIN table2 on table2.escola = table1.id
LEFT JOIN table3 on table3.id = table2.bairro
WHERE table1.situacao = 'EM_ATIVIDADE'
ORDER BY table1.id

См. Oracle документы для некоторых примеров.

0 голосов
/ 15 февраля 2019

Попробуйте изменить код следующим образом:

SELECT table1.nome, table1.id, LISTAGG(table1.nome, ', ') WITHIN GROUP (ORDER BY table1.nome, table1.id) as "bairro"
FROM table1
LEFT JOIN table2 on table2.escola = table1.id
LEFT JOIN table3 on table3.id = table2.bairro
WHERE table1.situacao = 'EM_ATIVIDADE'
GROUP BY table1.id, table1.nome
ORDER BY table1.id, table1.nome

Я добавил все выбранные столбцы, не относящиеся к LISTAGG, в GROUP BY, а также добавил их в ваше предложение LISTAGG's ORDER BY.

Кроме того, я также добавил table1.nome к ORDER BY всего вашего запроса, поскольку я понял, что после выполнения он будет заметно лучше.

Надеюсь, я помог!

...