2013-03-18 446 views
45

我正在嘗試聚合SQLServer中的「STRING」字段。我想在Oracle中找到與LISTAGG相同的函數。SQLSERVER中的ListAGG

你知道如何做同樣的功能或其他方法嗎?

例如,

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

而且我想這個查詢的結果將是

1 | AB 
2 | A 

回答

43

在SQL Server,你可以使用FOR XML PATH得到結果:

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; 

請參閱SQL Fiddle with Demo

+0

它worksssssssssss !!!!非常感謝您的幫助。 – user1557642 2013-03-18 13:28:36

+0

我想在子選擇中插入一個order by子句。你知道如何插入這個條款嗎? – user1557642 2013-03-18 13:38:29

+0

@ user1557642你想訂購什麼?你想要顛倒這些值嗎?你可以輕鬆地添加一個'ORDER BY'來看這個演示 - http://www.sqlfiddle.com/#!3/0836c/7。在這種情況下,'FieldA'的結果將顯示'BA' – Taryn 2013-03-18 13:39:14

66

在sqlserver的:

SELECT FieldA , STUFF((SELECT ','+ FieldB FROM TableName a 
WHERE b.FieldA = a.FieldA FOR XML PATH('')),1 ,1, '') Members 
FROM TableName b 
GROUP BY FieldA; 

在MySQL:

SELECT FieldA, GROUP_CONCAT(FieldB) AS Members 
FROM TableName 
GROUP BY FieldA 
ORDER BY FieldA; 

在Oracle:

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

偉大的答案 - 比標記的答案更簡潔一點+還提到其他SQL方言。這個sqlserver語法真的很不直觀。我也很驚訝,在選擇東西的附加括號是必要的。 – 2014-04-02 09:07:56

+0

@manas_kumar但是...爲什麼你使用STUFF?這是不必要的。我錯過了什麼嗎? – 2016-05-18 18:12:36

+0

@Ricardo_C在這裏使用STUFF來刪除前導逗號。 – DigitalDan 2016-06-01 06:31:55

16

在SQL Server 2017​​增加:

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 

此外,STRING_SPLIT是有用的相反的情況,並提供在SQL Server 2016

+2

STRING_AGG/STRING_SPLIT最近也被添加到Azure SQL數據庫中,以及任何碰巧在該平臺上登錄的人。 – 2017-03-23 04:22:32

+3

注意:vNext已被命名爲SQL Server 2017 – 2017-08-23 21:27:14

+0

您是否知道如何使用不同的c.name,因此所有連接的名稱都是唯一的? – 2018-02-21 13:16:45