Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ListAGG in SQLSERVER

I'm trying to aggregate a 'STRING' field in SQLServer. I would like to find the same function LISTAGG like in Oracle .

Do you know how to do the same function or an another method?

For Example,

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

And I would like that the result of this query will be

1 | AB 2 | A 
like image 243
user1557642 Avatar asked Mar 18 '13 13:03

user1557642


People also ask

What is SQL Listagg?

About LISTAGG. The LISTAGG function is used to aggregate a set of string values within a group into a single string by appending the string-expression values based on the order that's specified in the 'WITHIN GROUP' clause. As a single-set aggregate function, LISTAGG operates on all rows and returns a single output row ...

What is Listagg give an example?

Basic usage of Oracle LISTAGG() function For example, the following query returns a comma-separated list of employees for each job title. In this example, the LISTAGG() function concatenates the first names of employees who have the same job title.

What can I use instead of Listagg?

In order to concatenate field values, I would use “GROUP_CONCAT” function in Virtual DataPort Administration tool which is similar to LISTAGG function. For example, GROUP_CONCAT('<row separator>',<field_name>)

What does Listagg return?

The LISTAGG function returns a string value.


2 Answers

MySQL

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

Oracle & 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; 

SQL Server

SQL Server ≥ 2017 & 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 included to encourage the DRY principle)

  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

Ordering requires a CTE or subquery

  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; 

Without ordering

SELECT FieldA      , GROUP_CONCAT(FieldB, ',') AS FieldBs   FROM TableName  GROUP BY FieldA  ORDER BY FieldA; 
like image 156
Manas Kumar Avatar answered Oct 12 '22 00:10

Manas Kumar


Starting in SQL Server 2017 the STRING_AGG function is available which simplifies the logic considerably:

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

See SQL Fiddle with Demo

In SQL Server you can use FOR XML PATH to get the result:

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; 

See SQL Fiddle with Demo

like image 32
Taryn Avatar answered Oct 11 '22 22:10

Taryn