Lista AGG en SQLSERVER

Resuelto user1557642 asked hace 11 años • 4 respuestas

Estoy intentando agregar un campo 'STRING' en SQLServer. Me gustaría encontrar la misma función LISTAGG que en Oracle.

¿Sabes cómo hacer la misma función u otro método?

Por ejemplo,

Field A | Field B
1       |  A
1       |  B
2       |  A

Y me gustaría que el resultado de esta consulta fuera

1 | AB
2 | A
user1557642 avatar Mar 18 '13 20:03 user1557642
Aceptado

mysql

SELECT FieldA
     , GROUP_CONCAT(FieldB ORDER BY FieldB SEPARATOR ',') AS FieldBs
  FROM TableName
 GROUP BY FieldA
 ORDER BY FieldA;

Oráculo y DB2

SELECT FieldA
     , LISTAGG(FieldB, ',') WITHIN GROUP (ORDER BY FieldB) AS FieldBs
  FROM TableName
 GROUP BY FieldA
 ORDER BY FieldA;

PostgreSQL

SELECT FieldA
     , STRING_AGG(FieldB, ',' ORDER BY FieldB) AS FieldBs
  FROM TableName
 GROUP BY FieldA
 ORDER BY FieldA;

servidor SQL

Servidor SQL ≥ 2017 y Azure SQL

SELECT FieldA
     , STRING_AGG(FieldB, ',') WITHIN GROUP (ORDER BY FieldB) AS FieldBs
  FROM TableName
 GROUP BY FieldA
 ORDER BY FieldA;

SQL Server ≤ 2016 (CTE incluido para fomentar el principio DRY )

  WITH CTE_TableName AS (
       SELECT FieldA, FieldB
         FROM TableName)
SELECT t0.FieldA
     , STUFF((
       SELECT ',' + t1.FieldB
         FROM CTE_TableName t1
        WHERE t1.FieldA = t0.FieldA
        ORDER BY t1.FieldB
          FOR XML PATH('')), 1, LEN(','), '') AS FieldBs
  FROM CTE_TableName t0
 GROUP BY t0.FieldA
 ORDER BY FieldA;

SQLite

Realizar un pedido requiere un CTE o una subconsulta

  WITH CTE_TableName AS (
       SELECT FieldA, FieldB
         FROM TableName
        ORDER BY FieldA, FieldB)
SELECT FieldA
     , GROUP_CONCAT(FieldB, ',') AS FieldBs
  FROM CTE_TableName
 GROUP BY FieldA
 ORDER BY FieldA;

Sin ordenar

SELECT FieldA
     , GROUP_CONCAT(FieldB, ',') AS FieldBs
  FROM TableName
 GROUP BY FieldA
 ORDER BY FieldA;
Manas Kumar avatar Oct 13 '2013 18:10 Manas Kumar

A partir de SQL Server 2017 está disponible la STRING_AGGfunción que simplifica considerablemente la lógica:

select FieldA, string_agg(FieldB, '') as data
from yourtable
group by FieldA

Ver SQL Fiddle con demostración

En SQL Server puedes usar FOR XML PATHpara obtener el resultado:

select distinct t1.FieldA,
  STUFF((SELECT distinct '' + t2.FieldB
         from yourtable t2
         where t1.FieldA = t2.FieldA
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,0,'') data
from yourtable t1;

Ver SQL Fiddle con demostración

Taryn avatar Mar 18 '2013 13:03 Taryn

En SQL Server 2017 se agrega STRING_AGG :

SELECT t.name,STRING_AGG (c.name, ',') AS csv
FROM sys.tables t
JOIN sys.columns c on t.object_id = c.object_id
GROUP BY t.name
ORDER BY 1

Además, STRING_SPLIT es útil para el caso opuesto y está disponible en SQL Server 2016.

vldmrrdjcc avatar Jan 05 '2017 15:01 vldmrrdjcc

Esto también podría ser útil para alguien, es decir, para fines de análisis de datos y elaboración de perfiles de datos. (es decir, no agrupados por).

Antes de que existiera la función SQL Server 2017 STRING_AGG.

(es decir, devuelve solo una fila...)

SELECT DISTINCT
    SUBSTRING(
        STUFF((
            SELECT DISTINCT ',' + [FieldB] 
            FROM tablename 
            ORDER BY 1 
            FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)') 
        , 1, 0, '')
    , 2, 9999)
FROM tablename

Devuelve valores separados por comas, por ejemplo, "A,B".

Allan F avatar Jan 31 '2019 01:01 Allan F