次の方法で共有


STRING_AGG(Transact-SQL)

対象者: SQL Server 2017 (14.x) 以降のバージョン Azure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsSQL Analytics endpoint in Microsoft FabricWarehouse in Microsoft FabricSQL database in Microsoft Fabric

文字列式の値を連結し、値の間に区切り記号を挿入します。 文字列の末尾に区切り記号は追加されません。

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>

    結果の並べ替えに使用できる非定数 の一覧。 クエリごとに 1 つの <order_by_expression_list> のみを使用できます。 既定の並べ替え順は昇順です。

戻り値の型

戻り値の型は、最初の引数 (式) に依存します。 入力引数が文字列型 (nvarcharvarchar) の場合、結果の型は入力型と同じです。 次の表は自動変換の一覧です。

入力式の型 Result
nvarchar(max) nvarchar(max)
varchar(max) varchar(max)
nvarchar(1..4000) nvarchar(4000)
varchar(1..8000) varchar(8000)
intbigintsmallinttinyintnumericfloatrealbit
decimalsmallmoneymoneydatetimedatetime2
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 文字に切り詰められます。 この制限を引き上げるには、 [各列に表示される最大文字数] オプションを変更します。

記事とそのタグが異なるテーブルに分かれているデータベースがあると想定します。 開発者は、すべての関連するタグが付いた記事ごとに 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;...