STRING_AGG (Transact-SQL)
適用於:sql Server 2017 (14.x) 和更新版本的 Azure SQL 資料庫 Azure SQL 受控執行個體 Microsoft Fabric Warehouse Microsoft Fabric 中的 Azure Synapse AnalyticsSQL 分析端點
能串連字串運算式的值,並在這些值之間放置分隔符號值。 系統不會在字串結尾處新增分隔符號。
語法
STRING_AGG ( expression , separator ) [ <order_clause> ]
<order_clause> ::=
WITHIN GROUP ( ORDER BY <order_by_expression_list> [ ASC | DESC ] )
引數
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),則結果類型與輸入類型相同。 下表列出自動轉換:
輸入運算式類型 | 結果 |
---|---|
nvarchar(max) | nvarchar(max) |
varchar(max) | varchar(max) |
nvarchar(1..4000) | nvarchar(4000) |
varchar(1..8000) | varchar(8000) |
int、bigint、smallint、tinyint、數值、float、real、位、 十進制,smallmoney,money,datetime,datetime2 |
nvarchar(4000) |
備註
STRING_AGG
是一種彙總函式,此函數可擷取資料列中的所有運算式,並將它們串連成單一字串。 運算式值會以隱含方式轉換為字串類型,然後再行串連。 隱含轉換成字串會遵循現有的資料類型轉換規則。 如需資料類型轉換的詳細資訊,請參閱 CAST 和 CONVERT。
如果輸入表示式的類型為 varchar
會忽略 Null 值,而且不會新增對應的分隔符。 若要傳回 null 值的位置持有者,請使用 ISNULL
函式,如 範例 B所示。
STRING_AGG
可在任何相容性層級使用。
注意
<order_clause>
適用於資料庫相容性層級 110 (含) 以上。
範例
本文中的 Transact-SQL 程式代碼範例會使用 AdventureWorks2022
或 AdventureWorksDW2022
範例資料庫,您可以從 Microsoft SQL Server 範例和社群專案 首頁下載。
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
值不會在結果中傳回。
注意
如果使用 SQL Server Management Studio 查詢編輯器,[結果至方格] 選項無法實作歸位字元。 請切換至 [以文字顯示結果] 以正確地查看結果集。 根據預設,[以文字顯示結果] 會截斷為 256 個字元。 若要增加此限制,請變更 [每個資料行中顯示的最大字元數] 選項。
B. 產生以逗號分隔的名稱清單,不含 NULL
值
下列範例會將 Null 值取代為 'N/A',並在單一結果資料格中傳回以逗號分隔的名稱。
USE AdventureWorks2022;
GO
SELECT STRING_AGG(CONVERT (NVARCHAR (MAX), ISNULL(FirstName, 'N/A')), ',') AS csv
FROM Person.Person;
GO
以下是修剪的結果集。
csv
-----
Syed,Catherine,Kim,Kim,Kim,Hazem,Sam,Humberto,Gustavo,Pilar,Pilar, ...
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)
...
注意
如果使用 Management Studio 查詢編輯器,[結果至方格] 選項無法實作歸位字元。 請切換至 [以文字顯示結果] 以正確地查看結果集。
D. 傳回具有相關標籤的新聞文章
假設有一個資料庫,其中發行項及其標籤會分成不同的資料表。 開發人員希望針對每個發行項傳回單一資料列,並提供所有相關的標籤。 下列查詢可達成此結果:
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 |
注意
若 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
結果集如下所示。
注意
會顯示修剪過的結果。
城市 | 電子郵件 |
---|---|
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
結果集如下所示。
注意
會顯示修剪過的結果。
城市 | 電子郵件 |
---|---|
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 ... |