stuff string_agg one numeros concatenate concatenar column sql concatenation

string_agg - Concat todos los valores de columna en sql



stuff sql server (12)

¿Cómo concat todos los valores de columna de las filas diferenciadas devueltas de una consulta de SQL en un valor? Esto es un ejemplo:

una consulta devuelve:

FOO ------ RES1 RES2 RES3

Ahora quiero tener un resultado como el siguiente:

FOOCONCAT ----- RES1RES2RES3

¿Hay alguna manera de hacer esto en SQL?


Aquí está la respuesta que estás buscando; Tenía la sensación de que la solución estaba en la operación CONECTAR POR, simplemente no había usado la pseudocolumna SYS_CONNECT_BY_PATH anteriormente (que muestra la ruta completa al nodo en un árbol, separando los nombres de los nodos por una "/"). Suponiendo que su conjunto de valores "foo" antes son varias filas en una tabla, agrupadas por una columna "myKey", por ejemplo:

myKey foo -------- ---------- group 1 apple group 1 orange group 1 pear group 2 ape group 2 bear group 2 kitten

puede tratar los datos como si fueran un esquema de árbol y pretender que los valores de cada grupo representan nodos que bajan por una rama. En ese caso, harías esto:

SELECT myKey , SUBSTR(MAX(REPLACE(SYS_CONNECT_BY_PATH(foo, ''/'') ,''/'' ,'' '' ) ) ,2 ) FooConcat FROM ( SELECT MyKey , Foo , row_number() OVER (Partition by myKey order by myKey) NodeDepth FROM MyTable ) START WITH NodeDepth = 1 CONNECT BY PRIOR myKey = myKey AND PRIOR NodeDepth = NodeDepth -1 GROUP BY myKey ;

Por supuesto, el orden de los valores concatenados sería aleatorio; Si su tabla tuviera otra columna ("barra") que pudiera usar como campo de ordenamiento ascendente y contiguo, podría prescindir de la subconsulta (que solo existe para colocar una profundidad imaginaria en el árbol) y usar la tabla directamente. Sustituyendo NodeDepth con barra.



La concatenación de cadenas depende de la base de datos que está utilizando (no ha mencionado qué versión de su pregunta, así que aquí va) ...

En Oracle y DB2 puede usar la función CONCAT(string, string) ... CONCAT(string, string)

SQL Server puede usar el operador ''+'' ... string1 + string2 + string3

En MySQL es CONCAT(string, string... n_string)

Finalmente en PostgreSQL es TEXTCAT(string, string) ...

... Lo saqué de este pequeño y genial libro que tengo sentado en mi escritorio SQL Pocket Guide de O''Reilly ... ¡échale un vistazo!

:)


La forma mysql:

select group_concat(somecolumn separator '''') from sometable


La solución de Oracle de Quassnoi es bastante impresionante, pero found soluciones simpler utilizando SYS_CONNECT_BY_PATH () en lugar de la magia MODEL.

SELECT REPLACE(MAX(SYS_CONNECT_BY_PATH(foo, ''/'')), ''/'', '''') conc FROM ( SELECT T_FOO.*, ROW_NUMBER() OVER (ORDER BY FOO) R FROM T_FOO ) START WITH r=1 CONNECT BY PRIOR r = r-1;


Puede que no sea lo que estás buscando, pero he tenido buena suerte en el pasado con construcciones como esta:

SELECT MAX(DECODE(fookey, 1, foo, NULL)) || MAX(DECODE(fookey, 2, foo, NULL)) || MAX(DECODE(fookey, 3, foo, NULL)) || MAX(DECODE(fookey, 4, foo, NULL)) , groupingvalue FROM mytable GROUP BY groupingvalue;

Es independiente de la plataforma, y ​​funciona bien cuando tiene un número arbitrario, pero limitado de valores para foo, y se basan en algún otro valor clave. Por ejemplo, si tiene una tabla de facturas y desea ver todos los tiempos de línea de la factura en una sola fila, concatenada, y tiene un límite superior de 5 artículos de línea, se vería así:

SELECT MAX(DECODE(lineno, 1, foo, NULL)) || '', '' || MAX(DECODE(lineno, 2, foo, NULL)) || '', '' || MAX(DECODE(lineno, 3, foo, NULL)) || '', '' || MAX(DECODE(lineno, 4, foo, NULL)) || '', '' || MAX(DECODE(lineno, 5, foo, NULL)) , invoiceid FROM lineitem GROUP BY invoiceid;


SQL Server 2008 R2:

declare @ColumnNameList VARCHAR(MAX) SELECT @ColumnNameList = COALESCE(@ColumnNameList +'','' ,'''') + ColumnName FROM <<table name>> select @ColumnNameList


Seleccione ([col1] + '','' + [col2] + '','' + [col3] + '','' + [col4]) como [MiCol] De [Tabla]


Suponiendo que es una columna con varios valores, este enfoque funciona para MS SQL Server (no puedo hablar por otros sistemas).

declare @result varchar(max) set @result = '''' select @result = @result + RES from (query goes here)


Edición: desde la versión 8.4.0, CUBRID proporciona un 90% de compatibilidad con MySQL. Por lo tanto, admite GROUP_CONCAT que tiene una sintaxis similar a la de MySQL:

CREATE TABLE t(i int); INSERT INTO t VALUES (4),(2),(3),(6),(1),(5); SELECT GROUP_CONCAT(i*2+1 ORDER BY 1 SEPARATOR '''') FROM t; group_concat(i*2+1 order by 1 separator '''') ====================== ''35791113''

Bastante poderoso, ¿no es así? Y a continuación se muestra una solución alternativa soportada de forma nativa en CUBRID.

SELECT MAX(SYS_CONNECT_BY_PATH(s_name, '''')) AS conc_s_name FROM ( SELECT ROWNUM AS r, s_name FROM code ) AS res START WITH r = 1 CONNECT BY PRIOR r = r - 1;

Es tan interesante que esta forma de concatenar diferentes valores de columna de fila en CUBRID es casi idéntica a la forma de Oracle proporcionada por @devio. Sin embargo, en CUBRID parece un poco más fácil.


En SQL Server :

SELECT col1 AS [text()] FROM foo FOR XML PATH ('''')

En MySQL :

SELECT GROUP_CONCAT(col1 SEPARATOR '''') FROM foo

En PostgreSQL :

SELECT array_to_string ( ARRAY ( SELECT col1 FROM foo ), '''' )

En Oracle :

SELECT * FROM ( SELECT col1, ROW_NUMBER() OVER(ORDER BY 1) AS rn FROM foo MODEL DIMENSION BY (rn) MEASURES (col1, col1 AS group_concat, 0 AS mark) RULES UPDATE ( group_concat[rn > 1] = group_concat[CV() - 1] || col1[CV()], mark[ANY] = PRESENTV(mark[CV() + 1], 0, 1) ) ) WHERE mark = 1


select cast(res1 as varchar)+cast(res2 as varchar)+cast(res3 as varchar) as fooconcat from foo

Si las columnas ya son cadenas, no necesita la conversión, solo puede hacer:

select res1 + res2 + res3 as fooconcat from foo

Para datos de varias filas, utilice PIVOT .