STRING_AGG (Transact-SQL)

適用於:SQL Server 2017 (14.x) 及以後版本 Azure SQL 資料庫Azure SQL 管理實例Azure Synapse AnalyticsMicrosoft Fabric 中的 SQL 分析端點Microsoft Fabric 中的Warehouse 與 Microsoft Fabric 中的 SQL 資料庫

能串連字串運算式的值,並在這些值之間放置分隔符號值。 系統不會在字串結尾處新增分隔符號。

Transact-SQL 語法慣例

Syntax

STRING_AGG ( expression , separator ) [ <order_clause> ]

<order_clause> ::=
    WITHIN GROUP ( ORDER BY <order_by_expression_list> [ ASC | DESC ] )

Arguments

expression

任何類型的 運算式 。 在串連期間,運算式會轉換為 nvarchar 或 varchar 類型。 非字串類型會轉換成 nvarchar 類型。

separator

nvarchar 或 varchar 類型的運算式,用作串連字串的分隔符號。 這可以是常值或變數。

<order_clause>

選擇性地使用 WITHIN GROUP 子句指定串連結果的順序:

WITHIN GROUP ( ORDER BY <order_by_expression_list> [ ASC | DESC ] )
  • <order_by_expression_list>

    可用於排序結果的非常數 運算式 清單。 每個查詢只允許一個 <order_by_expression_list>。 預設排序順序為遞增。

傳回類型

傳回類型取決於第一個引數 (運算式)。 如果輸入引數是字串類型 (nvarchar、 varchar),則結果類型與輸入類型相同。 下表列出自動轉換:

輸入運算式類型 Result
nvarchar(max) nvarchar(max)
varchar(max) varchar(max)
nvarchar(1..4000) nvarchar(4000)
varchar(1..8000) varchar(8000)
整數、 bigint、 smallint、 tinyint、 數值、 浮點數、 實數、 位元、
十進制、 小錢、 金錢、 日期時間、 日期時間2
nvarchar(4000)

Remarks

STRING_AGG 是一種彙總函式,此函數可擷取資料列中的所有運算式,並將它們串連成單一字串。 運算式值會以隱含方式轉換為字串類型,然後再行串連。 隱含轉換成字串會遵循現有的資料類型轉換規則。 如需資料類型轉換的詳細資訊,請參閱 CAST 和 CONVERT。

如果輸入運算式是 varchar 類型,則分隔符號不能是 nvarchar 類型。

會忽略 Null 值,而且不會新增對應的分隔符。 若要傳回空值的預留位置,請使用ISNULL 所示的函式。

STRING_AGG 可在任何相容性層級使用。

Note

<order_clause> 適用於資料庫相容性層級 110 (含) 以上。

Examples

本文中的程式碼範例使用AdventureWorks2025了 or AdventureWorksDW2025 範例資料庫,你可以從 Azure Data SQL 範例倉庫的 GitHub 倉庫下載。

A. 產生名稱的清單,並以新行分隔

下列範例會在單一結果資料格中產生一份名稱的清單,並以歸位字元分隔這些名稱。

USE AdventureWorks2022;
GO

SELECT STRING_AGG(CONVERT (NVARCHAR (MAX), FirstName), CHAR(13)) AS csv
FROM Person.Person;
GO

結果集如下所示。

csv
-----------
Syed
Catherine
Kim
Kim
Kim
Hazem
...

在 NULL 資料格中找到的 name 值不會在結果中傳回。

Note

如果您使用 SQL Server Management Studio 查詢編輯器, 則 [結果至方格] 選項無法實作歸位字元。 請切換至 [以文字顯示結果] 以正確地查看結果集。 根據預設,[以文字顯示結果] 會截斷為 256 個字元。 若要增加此限制,請變更 [每個資料行中顯示的最大字元數] 選項。

B. 產生以逗號分隔的中間名稱清單,不含NULL 值

下列範例會 NULL 以 N/A 取代 值,並傳回單一結果單元格中以逗號分隔的名稱。

USE AdventureWorks2022;
GO

SELECT STRING_AGG(CONVERT (NVARCHAR (MAX), ISNULL(MiddleName, 'N/A')), ',') AS csv
FROM Person.Person;
GO

以下是修剪的結果集。

csv
-----
E,R.,N/A,N/A,B,E,N/A,N/A,N/A,N/A,G,B,N/A,C,J,L,P,N/A,M,N/A,N/A,N/A,L,J., ...

C. 產生以逗號分隔的值

USE AdventureWorks2022;
GO

SELECT STRING_AGG(CONVERT (NVARCHAR (MAX), CONCAT(FirstName, ' ', LastName, '(', ModifiedDate, ')')), CHAR(13)) AS names
FROM Person.Person;
GO

以下是修剪的結果集。

names
-------
Ken Sánchez (Feb 8 2003 12:00AM)
Terri Duffy (Feb 24 2002 12:00AM)
Roberto Tamburello (Dec 5 2001 12:00AM)
Rob Walters (Dec 29 2001 12:00AM)
...

Note

如果您使用 SQL Server Management Studio 查詢編輯器, 則 [結果至方格] 選項無法實作歸位字元。 請切換至 [以文字顯示結果] 以正確地查看結果集。 根據預設,[以文字顯示結果] 會截斷為 256 個字元。 若要增加此限制,請變更 [每個資料行中顯示的最大字元數] 選項。

假設有一個資料庫,其中發行項及其標籤會分成不同的資料表。 開發人員希望針對每個發行項傳回單一資料列,並提供所有相關的標籤。 下列查詢可達成此結果:

SELECT a.articleId,
       title,
       STRING_AGG(tag, ',') AS tags
FROM dbo.Article AS a
     LEFT OUTER JOIN dbo.ArticleTag AS t
         ON a.ArticleId = t.ArticleId
GROUP BY a.articleId, title;
GO

結果集如下所示。

articleId title tags
172 Polls indicate close election results politics,polls,city council
176 New highway expected to reduce congestion NULL
177 Dogs continue to be more popular than cats polls,animals

Note

若 GROUP BY 函式不是 STRING_AGG 清單中的唯一項目,則 SELECT 子句為必要項目。

E. 產生每個鄉鎮的電子郵件清單

下列查詢會尋找員工的電子郵件地址,並依城市分組:

USE AdventureWorks2022;
GO

SELECT TOP 10 City,
              STRING_AGG(CONVERT (NVARCHAR (MAX), EmailAddress), ';') AS emails
FROM Person.BusinessEntityAddress AS BEA
     INNER JOIN Person.Address AS A
         ON BEA.AddressID = A.AddressID
     INNER JOIN Person.EmailAddress AS EA
         ON BEA.BusinessEntityID = EA.BusinessEntityID
GROUP BY City;
GO

以下是修剪的結果集。

City emails
Ballard paige28@adventure-works.com;joshua24@adventure-works.com;;javier12@adventure-works.com...
Baltimore gilbert9@adventure-works.com
Barstow kristen4@adventure-works.com
Basingstoke Hants dale10@adventure-works.com;heidi9@adventure-works.com
Baytown kelvin15@adventure-works.com
Beaverton billy6@adventure-works.com;dalton35@adventure-works.com;;lawrence1@adventure-works.com...
Bell Gardens christy8@adventure-works.com
Bellevue min0@adventure-works.com;gigi0@adventure-works.com;;terry18@adventure-works.com...
Bellflower philip0@adventure-works.com;emma34@adventure-works.com;;jorge8@adventure-works.com...
Bellingham christopher23@adventure-works.com;frederick7@adventure-works.com;;omar0@adventure-works.com...

在電子郵件資料行中傳回的電子郵件,可以直接用來傳送電子郵件給在一些特定城市工作的人員群組。

F. 產生每個鄉鎮的排序電子郵件清單

與上一個範例相類似,下列查詢會尋找員工的電子郵件地址,依城市分組,並按字母順序排序電子郵件:

USE AdventureWorks2022;
GO

SELECT TOP 10 City,
              STRING_AGG(CONVERT (NVARCHAR (MAX), EmailAddress), ';') WITHIN GROUP (ORDER BY EmailAddress ASC) AS Emails
FROM Person.BusinessEntityAddress AS BEA
     INNER JOIN Person.Address AS A
         ON BEA.AddressID = A.AddressID
     INNER JOIN Person.EmailAddress AS EA
         ON BEA.BusinessEntityID = EA.BusinessEntityID
GROUP BY City;
GO

以下是修剪的結果集。

City Emails
Barstow kristen4@adventure-works.com
Basingstoke Hants dale10@adventure-works.com;heidi9@adventure-works.com
Braintree mindy20@adventure-works.com
Bell Gardens christy8@adventure-works.com
Byron louis37@adventure-works.com
Bordeaux ranjit0@adventure-works.com
Carnation don0@adventure-works.com;douglas0@adventure-works.com;;george0@adventure-works.com...
Boulogne-Billancourt allen12@adventure-works.com;bethany15@adventure-works.com;;carl5@adventure-works.com...
Berkshire barbara41@adventure-works.com;brenda4@adventure-works.com;;carrie14@adventure-works.com...
Berks adriana6@adventure-works.com;alisha13@adventure-works.com;;arthur19@adventure-works.com...