Função LISTAGG do Oracle é uma função analítica que nos permite concatenar as strings para meter_column para cada GROUP com base na order_by_clause. Isso está presente no Oracle a partir do 11gR2
A sintaxe para a função LISTAGG no Oracle é
LISTAGG (measure_column [, 'delimiter'])
WITHIN GROUP (order_by_clause) [OVER (query_partition_clause)]
Explicação dos termos
measure_column | A coluna ou expressão cujos valores você deseja concatenar no conjunto de resultados. Valores nulos na medida_coluna são ignorados. |
Delimitador | Opcional. É o delimitador a ser usado ao separar a measure_column valores ao gerar os resultados. |
order_by_clause | Determina a ordem em que os valores concatenados são retornados |
Vamos ver alguns casos e exemplos na função LISTAGG
1) Como uma função agregada de conjunto único, LISTAGG opera em todas as linhas e retorna uma única linha de saída.
SELECT LISTAGG(first_name, '; ')
WITHIN GROUP (ORDER BY hire_date, last_name) "Employee_list",
MIN(hire_date) "Earliest"
FROM emp
WHERE dept_no = 30;Employee_list Earliest
------------------------------------------------------------ ---------
TOM; BOB; BILL 17-JUN-18
2) Como um agregado de conjunto de grupos, a função opera e retorna uma linha de saída para cada grupo definido pela cláusula GROUP BY.
COLUMN employees FORMAT A50
SELECT deptno, LISTAGG(ename, ';') WITHIN GROUP (ORDER BY ename) AS employees
FROM emp
GROUP BY deptno;
DEPTNO EMPLOYEES
---------- --------------------------------------------------
10 JOSHUA,KING,MILLER
20 AJAY,FANES,SCOTT,SMITH
30 TOM; BOB; BILLMore Example
select table_name,
listagg(index_name, ',') within group (order by index_name) all_inds
from user_indexes
group by table_name;
3) Como uma função analítica, LISTAGG particiona o conjunto de resultados da consulta em grupos com base em uma ou mais expressões na query_partition_clause.
SQL> SELECT deptno
, ename
, hiredate
, LISTAGG(ename, ',')
WITHIN GROUP (ORDER BY hiredate)
OVER (PARTITION BY deptno) AS employees
FROM emp order by deptno;DEPTNO ENAME HIREDATE EMPLOYEES
---------- ---------- ----------- -------------------------------------
10 JOSHUA 09/06/2018 JOSHUA,KING,MILLER
10 KING 17/11/2018 JOSHUA,KING,MILLER
10 MILLER 23/01/2018 JOSHUA,KING,MILLER
20 AJAY 17/12/2018 AJAY,FANES,SCOTT,SMITH
20 FANES 02/04/2018 AJAY,FANES,SCOTT,SMITH
20 SCOTT 19/04/2018 AJAY,FANES,SCOTT,SMITH
20 SMITH 23/05/2018 AJAY,FANES,SCOTT,SMITH
30 TOM 20/02/2018 TOM; BOB; BILL
30 BOB 22/02/2018 TOM; BOB; BILL
30 BILL 01/05/2018 TOM; BOB; BILL
Adição na função LISTAGG do banco de dados Oracle 12cR2
O número máximo de retornos de caracteres é de 4000 bytes e se exceder, dá o erro
ORA-01489:o resultado da concatenação de strings é muito longo
Com o Oracle 12cR2, a Oracle forneceu uma cláusula sobre overflow truncate para lidar com erros de estouro normalmente
listagg (
measure, ','
[ on overflow (truncate|error) ]
[ text ] [ (with|without) count ]
) within group (order by cols)
Agora você pode dizer explicitamente se deseja erro ou semântica de truncamento. Os códigos pré 12cR2 funcionam bem, pois esse é o comportamento padrão
Agora suponha que você não queira retornar um erro quando ele cruzar 4k bytes, então no overflow truncate é a solução.
select table_name,
listagg(index_name, ',' on overflow truncate) within group (order by index_name) inds
from user_indexes
group by table_name;
Caso ocorra truncamento, o Oracle truncará de volta para o próximo valor completo. Nesse ponto, você poderá controlar como informará ao usuário que a lista foi truncada. Por padrão, anexamos três pontos ‘…’ à string como indicador de que ocorreu truncamento. Você pode alterar o '….' se quiser, pode substituir isso
Se você quiser substituir “…” por “mais”, “extra” ou um hiperlink “clique para mais”, basta fornecer sua nova string!
select table_name,
listagg(index_name, ',' on overflow truncate
'|||'
) within group (order by index_name) inds
from user_indexes
group by table_name;
Por padrão, truncate mostra a contagem de valores ausentes Se não quiser mostrar a contagem, use sem contagem
select table_name,
listagg(index_name, ',' on overflow truncate '....' without count) within group (order by index_name) inds
from user_indexes
group by table_name;
Solução pré 11GR2 (10g, 9i, 11gR1)
Se você não estiver executando o 11g Release 2 ou superior, mas estiver executando uma versão do banco de dados em que a função WM_CONCAT está presente, então é uma solução de esforço zero, pois executa a agregação para você. Na verdade, é um exemplo de uma função agregada definida pelo usuário descrita abaixo, mas a Oracle fez todo o trabalho para você.
COLUMN employees FORMAT A50
SELECT deptno, wm_concat(ename) AS employees
FROM emp
GROUP BY deptno;
EPTNO EMPLOYEES
---------- --------------------------------------------------
10 JOSHUA,KING,MILLER
20 AJAY,FANES,SCOTT,SMITH
30 TOM; BOB; BILL
Isso também pode ser feito por meio de uma função definida pelo usuário. Eu recomendaria verificar o link abaixo do asktom. Isso é leitura obrigatória
Opção alternativa Listagg
Espero que você goste do conteúdo desta postagem sobre a Função LISTAGG do Oracle
Artigos relacionados
Coluna de incremento automático - Sequência como valor padrão no Oracle e mysql
Juntos Oracle
Operadores de conjunto SQL
Como usar o URL do google translate no Oracle plsql
Funções de linha única em sql
função de data no oráculo