STRING_AGG (Transact-SQL)
適用対象: SQL Server 2017 (14.x) 以降 Azure SQL DatabaseAzure SQL Managed InstanceAzure Synapse Analytics Microsoft Fabric のSQL 分析エンドポイント Microsoft Fabric のウェアハウス
文字列式の値を連結し、値の間に区切り記号を挿入します。 文字列の末尾に区切り記号は追加されません。
構文
STRING_AGG ( expression , separator ) [ <order_clause> ]
<order_clause> ::=
WITHIN GROUP ( ORDER BY <order_by_expression_list> [ ASC | DESC ] )
引数
式 (expression)
任意の型の 式。 式は、連結時に
separator
連結された文字列の区切り文字として使用 nvarchar 型または varchar 型の 式。 リテラルまたは変数を使用できます。
<order_clause>
必要に応じて、WITHIN GROUP
句を使用して連結結果の順序を指定します。
WITHIN GROUP ( ORDER BY <order_by_expression_list> [ ASC | DESC ] )
<order_by_expression_list>
結果を並べ替えるために使用できる、定数ではない式のリスト。 クエリごとに 1 つの
<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, numeric, float, real, bit, 10 進数、 smallmoney、 money, datetime, datetime2 |
nvarchar(4000) |
注釈
STRING_AGG
は、すべての式を行から取り出し、それらを 1 つの文字列に連結する集計関数です。 式の値は、暗黙的に文字列型に変換され、連結されます。 文字列への暗黙の変換は、データ型変換の既存の規則に従います。 データ型変換の詳細については、CAST および CONVERT
入力式が varchar
Null 値は無視され、対応する区切り記号は追加されません。 null 値のプレース ホルダーを返すには、Bの例で示すように、
STRING_AGG
は任意の互換性レベルで使用できます。
Note
<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
値は結果で返されません。
Note
SQL Server Management Studio クエリ エディターを使用している場合、結果を Grid オプションに実装することはできません。 結果セットを正しく表示するには、[結果をテキストで表示] に切り替えてください。 [結果をテキストで表示] は既定では、256 文字に切り詰められます。 この制限を引き上げるには、 [各列に表示される最大文字数] オプションを変更します。
B.
NULL
値を指定せずにコンマで区切られた名前のリストを生成する
次の例では、null 値を 'N/A' に置き換え、コンマで区切った名前を 1 つの結果セルに返します。
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)
...
Note
Management Studio クエリ エディターを使用している場合、結果からグリッドへの オプションは復帰を実装できません。 結果セットを正しく表示するには、[結果をテキストで表示] に切り替えてください。
D. 関連するタグが付いたニュース記事を返す
記事とそのタグが異なるテーブルに分かれているデータベースがあると想定します。 開発者は、すべての関連するタグが付いた記事ごとに 1 つの行を返したいと考えています。 次のクエリでは、この結果が得られます。
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
結果セットは次のとおりです。
Note
結果はトリミングされて表示されます。
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 ;... |
emails 列に返された電子メール アドレスは、特定の市区町村で働く従業員のグループに電子メールを送信する場合にそのまま使用できます。
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
結果セットは次のとおりです。
Note
結果はトリミングされて表示されます。
City | メール |
---|---|
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 ;... |