¿Sería posible construir SQL para concatenar valores de columna de múltiples filas?
Lo siguiente es un ejemplo:
Tabla A
PID UNA si C
Tabla B
PID SEQ Desc A 1 Have A 2 un bonito A 3 días. B 1 Buen trabajo. C 1 Sí C 2 podemos C 3 do C 4 este trabajo!
La salida del SQL debe ser:
PID Desc Que tengas un buen día. B Buen trabajo. C Sí, podemos hacer este trabajo!
Entonces, ¿básicamente la columna Desc para la tabla de salida es una concatenación de los valores SEQ de la Tabla B?
¿Alguna ayuda con el SQL?
sql
oracle
string-aggregation
jagamot
fuente
fuente
Respuestas:
Existen algunas formas según la versión que tenga: consulte la documentación de Oracle sobre técnicas de agregación de cadenas . Una muy común es usar
LISTAGG
:Luego únete a
A
para elegir lopids
que quieras.Nota: Fuera de la caja,
LISTAGG
solo funciona correctamente conVARCHAR2
columnas.fuente
También hay una
XMLAGG
función, que funciona en versiones anteriores a 11.2. Debido aWM_CONCAT
que no está documentado ni respaldado por Oracle , se recomienda no usarlo en el sistema de producción.Con
XMLAGG
usted puede hacer lo siguiente:Lo que esto hace es
ename
columna (concatenados con una coma) de laemployee_names
tabla en un elemento xml (con la etiqueta E)fuente
Con la cláusula del modelo SQL:
Escribí sobre esto aquí . Y si sigue el enlace al hilo OTN, encontrará algo más, incluida una comparación de rendimiento.
fuente
La función analítica LISTAGG se introdujo en Oracle 11g Release 2 , por lo que es muy fácil agregar cadenas. Si está utilizando 11g Release 2, debe usar esta función para la agregación de cadenas. Consulte la siguiente URL para obtener más información sobre la concatenación de cadenas.
http://www.oracle-base.com/articles/misc/StringAggregationTechniques.php
Concatenación de cuerdas
fuente
Como la mayoría de las respuestas sugieren,
LISTAGG
es la opción obvia. Sin embargo, un aspecto molestoLISTAGG
es que si la longitud total de la cadena concatenada excede los 4000 caracteres (límiteVARCHAR2
en SQL), se genera el siguiente error, que es difícil de administrar en las versiones de Oracle hasta 12.1Una nueva característica agregada en 12cR2 es la
ON OVERFLOW
cláusula deLISTAGG
. La consulta que incluye esta cláusula se vería así:Lo anterior restringirá la salida a 4000 caracteres pero no arrojará el
ORA-01489
error.Estas son algunas de las opciones adicionales de la
ON OVERFLOW
cláusula:ON OVERFLOW TRUNCATE 'Contd..'
: Esto se mostrará'Contd..'
al final de la cadena (el valor predeterminado es...
)ON OVERFLOW TRUNCATE ''
: Esto mostrará los 4000 caracteres sin ninguna cadena de terminación.ON OVERFLOW TRUNCATE WITH COUNT
: Esto mostrará el número total de caracteres al final después de los caracteres de terminación. Por ejemplo: - '...(5512)
'ON OVERFLOW ERROR
: Si esperaLISTAGG
que falle con elORA-01489
error (que de todos modos es el predeterminado).fuente
Para aquellos que deben resolver este problema usando Oracle 9i (o anterior), probablemente necesitarán usar SYS_CONNECT_BY_PATH, ya que LISTAGG no está disponible.
Para responder al OP, la siguiente consulta mostrará el PID de la Tabla A y concatenará todas las columnas DESC de la Tabla B:
También puede haber casos en los que las claves y los valores están contenidos en una tabla. La siguiente consulta se puede usar donde no hay Tabla A, y solo existe la Tabla B:
Todos los valores se pueden reordenar como se desee. Las descripciones concatenadas individuales se pueden reordenar en la cláusula PARTITION BY, y la lista de PID se puede reordenar en la cláusula ORDER BY final.
Alternativamente: puede haber ocasiones en las que desee concatenar todos los valores de una tabla completa en una fila.
La idea clave aquí es usar un valor artificial para el grupo de descripciones que se concatenarán.
En la siguiente consulta, se usa la cadena constante '1', pero cualquier valor funcionará:
Las descripciones concatenadas individuales se pueden reordenar en la cláusula PARTITION BY.
Varias otras respuestas en esta página también han mencionado esta referencia extremadamente útil: https://oracle-base.com/articles/misc/string-aggregation-techniques
fuente
LISTAGG ofrece el mejor rendimiento si la clasificación es obligatoria (00: 00: 05.85)
SELECT pid, LISTAGG(Desc, ' ') WITHIN GROUP (ORDER BY seq) AS description FROM B GROUP BY pid;
COLLECT ofrece el mejor rendimiento si no es necesario ordenar (00: 00: 02.90):
SELECT pid, TO_STRING(CAST(COLLECT(Desc) AS varchar2_ntt)) AS Vals FROM B GROUP BY pid;
COLLECT con pedidos es un poco más lento (00: 00: 07.08):
SELECT pid, TO_STRING(CAST(COLLECT(Desc ORDER BY Desc) AS varchar2_ntt)) AS Vals FROM B GROUP BY pid;
Todas las demás técnicas fueron más lentas.
fuente
Antes de ejecutar una consulta de selección, ejecute esto:
SET SERVEROUT ON SIZE 6000
fuente
Prueba este código:
fuente
En la selección donde desea su concatenación, llame a una función SQL.
Por ejemplo:
Luego para la función SQL:
La sintaxis del encabezado de función puede ser incorrecta, pero el principio funciona.
fuente