解決策
最適の定義 変更することもできますが、通常のTransactSQLを使用してさまざまな行の文字列を連結する方法を次に示します。これはAzureで正常に機能するはずです。
;WITH Partitioned AS
(
SELECT
ID,
Name,
ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Name) AS NameNumber,
COUNT(*) OVER (PARTITION BY ID) AS NameCount
FROM dbo.SourceTable
),
Concatenated AS
(
SELECT
ID,
CAST(Name AS nvarchar) AS FullName,
Name,
NameNumber,
NameCount
FROM Partitioned
WHERE NameNumber = 1
UNION ALL
SELECT
P.ID,
CAST(C.FullName + ', ' + P.Name AS nvarchar),
P.Name,
P.NameNumber,
P.NameCount
FROM Partitioned AS P
INNER JOIN Concatenated AS C
ON P.ID = C.ID
AND P.NameNumber = C.NameNumber + 1
)
SELECT
ID,
FullName
FROM Concatenated
WHERE NameNumber = NameCount
説明
アプローチは3つのステップに要約されます:
-
OVER
を使用して行に番号を付けます およびPARTITION
連結の必要に応じて、それらをグループ化して順序付けします。結果はPartitioned
CTE。後で結果をフィルタリングするために、各パーティションの行数を保持します。 -
再帰CTEの使用(
Concatenated
)行番号を繰り返し処理します(NameNumber
列)Name
を追加しますFullName
の値 列。 -
NameNumber
が最も高い結果を除くすべての結果を除外します 。
このクエリを予測可能にするには、両方のグループ化を定義する必要があることに注意してください(たとえば、同じID
のシナリオ行で 連結されます)および並べ替え(連結の前に文字列をアルファベット順に並べ替えると仮定しました)。
次のデータを使用して、SQLServer2012でソリューションをすばやくテストしました。
INSERT dbo.SourceTable (ID, Name)
VALUES
(1, 'Matt'),
(1, 'Rocks'),
(2, 'Stylus'),
(3, 'Foo'),
(3, 'Bar'),
(3, 'Baz')
クエリ結果:
ID FullName
----------- ------------------------------
2 Stylus
3 Bar, Baz, Foo
1 Matt, Rocks