対象者: SQL Server 2017 (14.x) 以降のバージョン
Azure SQL Database
Azure SQL Managed Instance
Azure Synapse Analytics
SQL Analytics endpoint in Microsoft Fabric
Warehouse in Microsoft Fabric
SQL database in Microsoft Fabric
文字列式の値を連結し、値の間に区切り記号を挿入します。 文字列の末尾に区切り記号は追加されません。
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>結果の並べ替えに使用できる非定数 式 の一覧。 クエリごとに 1 つの
<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) |
|
int、 bigint、 smallint、 tinyint、 numeric、 float、 real、 bit、 decimal、 smallmoney、 money、 datetime、 datetime2 |
nvarchar(4000) |
Remarks
STRING_AGG は、すべての式を行から取り出し、それらを 1 つの文字列に連結する集計関数です。 式の値は、暗黙的に文字列型に変換され、連結されます。 文字列への暗黙の変換は、データ型変換の既存の規則に従います。 データ型変換の詳細については、CAST および CONVERT
入力式が varchar 型の場合、区切り記号を nvarchar 型にすることはできません。
Null 値は無視され、対応する区切り記号は追加されません。 null 値のプレース ホルダーを返すには、ISNULL に示すように関数を使用します。
STRING_AGG は任意の互換性レベルで使用できます。
Note
<order_clause> は、データベース互換性レベル 110 以上で使用できます。
Examples
この記事のコード サンプルでは、AdventureWorks2025 または AdventureWorksDW2025 サンプル データベースを使用します。このサンプル データベースは、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 クエリ エディターを使用する場合、[ 結果からグリッド] オプションでは復帰を実装できません。 結果セットを正しく表示するには、[結果をテキストで表示] に切り替えてください。 [結果をテキストで表示] は既定では、256 文字に切り詰められます。 この制限を引き上げるには、 [各列に表示される最大文字数] オプションを変更します。
B. NULL 値を指定せずにコンマで区切られたミドル ネームのリストを生成する
次の例では、 NULL 値を N/A に置き換え、1 つの結果セルでコンマで区切られた名前を返します。
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 文字に切り詰められます。 この制限を引き上げるには、 [各列に表示される最大文字数] オプションを変更します。
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
トリミングされた結果セットを次に示します。
| 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
トリミングされた結果セットを次に示します。
| 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;... |