sql >> Base de Datos >  >> RDS >> Oracle

Cómo usar la función Oracle LISTAGG

Función Oracle LISTAGG es una función analítica que nos permite concatenar las cadenas de medida_columna para cada GRUPO en función de la cláusula order_by_. Esto está presente en Oracle desde 11gR2

La sintaxis de la función LISTAGG en Oracle es

LISTAGG (measure_column [, 'delimiter'])
WITHIN GROUP (order_by_clause) [OVER (query_partition_clause)]

Explicación de términos

medida_columna La columna o expresión cuyos valores desea concatenar en el conjunto de resultados. Los valores nulos en la columna_medida se ignoran.
Delimitador Opcional. Es el delimitador que se utiliza al separar measure_column valores al mostrar los resultados.
pedir_por_cláusula Determina el orden en que se devuelven los valores concatenados

Veamos algunos casos y ejemplos en la función LISTAGG

1) Como función agregada de conjunto único, LISTAGG opera en todas las filas y devuelve una sola fila de salida.

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 agregado de un conjunto de grupos, la función opera y devuelve una fila de salida para cada grupo definido por la 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; BILL

More Example

select table_name,
listagg(index_name, ',') within group (order by index_name) all_inds
from user_indexes
group by table_name;

3) Como función analítica, LISTAGG divide el conjunto de resultados de la consulta en grupos según una o más expresiones en 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

Agregado en la función LISTAGG de la base de datos Oracle 12cR2

El número máximo de caracteres devueltos es de 4000 bytes y si excede, da el error

ORA-01489:el resultado de la concatenación de cadenas es demasiado largo

Con Oracle 12cR2, Oracle ha proporcionado una cláusula sobre truncamiento de desbordamiento para manejar los errores de desbordamiento con gracia

listagg (
measure, ','
[ on overflow (truncate|error) ]
[ text ] [ (with|without) count ]
) within group (order by cols)

Ahora puede decir explícitamente si desea una semántica de error o de truncamiento. Los códigos anteriores a 12cR2 funcionan bien, ya que ese es el comportamiento predeterminado

Ahora suponga que no desea devolver un error cuando cruza 4k bytes, luego en desbordamiento truncado es la solución.

select table_name,
listagg(index_name, ',' on overflow truncate) within group (order by index_name) inds
from user_indexes
group by table_name;

En caso de que se produzca un truncamiento, Oracle volverá a truncar al siguiente valor completo, momento en el que puede controlar cómo le dice al usuario que la lista se ha truncado. De forma predeterminada, agregamos tres puntos '...' a la cadena como indicador de que se ha producido un truncamiento. Puede cambiar el '....' si lo desea, puede anularlo

Si desea reemplazar "..." con "más", "extra" o un hipervínculo "haga clic para obtener más", ¡simplemente proporcione su nueva cadena!

select table_name,
listagg(index_name, ',' on overflow truncate
'|||'
) within group (order by index_name) inds
from user_indexes
group by table_name;

De forma predeterminada, truncar muestra el recuento de valores faltantes. Si no desea mostrar el recuento, utilice sin recuento

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;

Solución Pre 11GR2 (10g, 9i, 11gR1)

Si no está ejecutando 11g Release 2 o superior, pero está ejecutando una versión de la base de datos donde está presente la función WM_CONCAT, entonces es una solución sin esfuerzo ya que realiza la agregación por usted. En realidad, es un ejemplo de una función agregada definida por el usuario que se describe a continuación, pero Oracle ha hecho todo el trabajo por usted.

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

Esto también se puede lograr a través de la función definida por el usuario. Recomendaría consultar el siguiente enlace asktom. Esto debe leerse

Opción alternativa Listagg

Espero que les guste el contenido de esta publicación sobre  Función Oracle LISTAGG

Artículos relacionados
Columna de incremento automático:secuencia como valor predeterminado en Oracle y mysql
Oracle se une
Operadores de conjunto de Sql
Cómo utilizar Google Translate URL en Oracle plsql
Funciones de fila única en sql
función de fecha en Oracle