次の方法で共有


STRING_AGG (Transact-SQL)

Applies to: SQL Server 2017 (14.x) and later Azure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsSQL analytics endpoint in Microsoft FabricWarehouse 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

An expression of any type. Expressions are converted to nvarchar or varchar types during concatenation. Non-string types are converted to nvarchar type.

separator

An expression of nvarchar or varchar type that is used as separator for concatenated strings. リテラルまたは変数を使用できます。

<order_clause>

必要に応じて、WITHIN GROUP 句を使用して連結結果の順序を指定します。

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

    A list of non-constant expressions that can be used for sorting results. クエリごとに 1 つの <order_by_expression_list> のみを使用できます。 既定の並べ替え順は昇順です。

Return types

戻り値の型は、最初の引数 (式) に依存します。 If input argument is string type (nvarchar, varchar), the result type is the same as the input type. 次の表は自動変換の一覧です。

入力式の型 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参照してください。

If the input expression is type varchar, the separator can't be type nvarchar.

Null 値は無視され、対応する区切り記号は追加されません。 To return a place holder for null values, use the ISNULL function as demonstrated in example B.

STRING_AGG は任意の互換性レベルで使用できます。

Note

<order_clause> は、データベース互換性レベル 110 以上で使用できます。

Examples

この記事のコード サンプルでは、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 クエリ エディターを使用する場合、[ 結果からグリッド] オプションでは復帰を実装できません。 結果セットを正しく表示するには、[結果をテキストで表示] に切り替えてください。 [結果をテキストで表示] は既定では、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;...