[解決済み】サブクエリから複数行を1つの区切りフィールドに「結合」するSQL Server関数を作成する方法とは?[重複している]。
2022-04-13 21:19:38
質問
説明のために、次のような2つのテーブルがあるとします。
VehicleID Name
1 Chuck
2 Larry
LocationID VehicleID City
1 1 New York
2 1 Seattle
3 1 Vancouver
4 2 Los Angeles
5 2 Houston
次のような結果を返すクエリを書きたい。
VehicleID Name Locations
1 Chuck New York, Seattle, Vancouver
2 Larry Los Angeles, Houston
サーバーサイドのカーソルを使ってできることは知っています。
DECLARE @VehicleID int
DECLARE @VehicleName varchar(100)
DECLARE @LocationCity varchar(100)
DECLARE @Locations varchar(4000)
DECLARE @Results TABLE
(
VehicleID int
Name varchar(100)
Locations varchar(4000)
)
DECLARE VehiclesCursor CURSOR FOR
SELECT
[VehicleID]
, [Name]
FROM [Vehicles]
OPEN VehiclesCursor
FETCH NEXT FROM VehiclesCursor INTO
@VehicleID
, @VehicleName
WHILE @@FETCH_STATUS = 0
BEGIN
SET @Locations = ''
DECLARE LocationsCursor CURSOR FOR
SELECT
[City]
FROM [Locations]
WHERE [VehicleID] = @VehicleID
OPEN LocationsCursor
FETCH NEXT FROM LocationsCursor INTO
@LocationCity
WHILE @@FETCH_STATUS = 0
BEGIN
SET @Locations = @Locations + @LocationCity
FETCH NEXT FROM LocationsCursor INTO
@LocationCity
END
CLOSE LocationsCursor
DEALLOCATE LocationsCursor
INSERT INTO @Results (VehicleID, Name, Locations) SELECT @VehicleID, @Name, @Locations
END
CLOSE VehiclesCursor
DEALLOCATE VehiclesCursor
SELECT * FROM @Results
しかし、ご覧の通り、これには膨大なコードが必要です。 私が欲しいのは、このようなことを可能にする汎用的な関数です。
SELECT VehicleID
, Name
, JOIN(SELECT City FROM Locations WHERE VehicleID = Vehicles.VehicleID, ', ') AS Locations
FROM Vehicles
このようなことは可能でしょうか? それとも似たようなこと?
解決方法は?
SQL Server 2005 を使用している場合、FOR XML PATH コマンドを使用することができました。
SELECT [VehicleID]
, [Name]
, (STUFF((SELECT CAST(', ' + [City] AS VARCHAR(MAX))
FROM [Location]
WHERE (VehicleID = Vehicle.VehicleID)
FOR XML PATH ('')), 1, 2, '')) AS Locations
FROM [Vehicle]
カーソルを使うよりずっと簡単で、かなりうまくいくようです。
更新情報
新しいバージョンの SQL Server でこの方法をまだ使っている人のために、もう少し簡単でパフォーマンスも高い
STRING_AGG
というメソッドがSQL Server 2017から提供されています。
SELECT [VehicleID]
,[Name]
,(SELECT STRING_AGG([City], ', ')
FROM [Location]
WHERE VehicleID = V.VehicleID) AS Locations
FROM [Vehicle] V
また、2番目のパラメータに別のセパレータを指定することができ、前者の方法よりも少し柔軟性があります。
関連
-
[解決済み] SQL ServerでSELECTからUPDATEする方法とは?
-
[解決済み] SQL Server で複数行のテキストを 1 つのテキスト文字列に連結する方法
-
[解決済み] SQL Server の DateTime データ型から日付だけを返す方法
-
[解決済み] SQL ServerでJOINを使用してUPDATE文を実行するにはどうすればよいですか?
-
[解決済み] MySQLの複数行を1つのフィールドに連結することはできますか?
-
[解決済み] SQL Serverでシングルクォートをエスケープするにはどうすればよいですか?
-
[解決済み] Oracleの全テーブルのリストを取得しますか?
-
[解決済み] SQL Serverでテーブルからカラム名を取得するにはどうすればよいですか?
-
[解決済み] T-SQLでnot equalには!=と<>のどちらを使うべきですか?
-
[解決済み] SQL ServerでINNER JOINを使用して削除するにはどうすればよいですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
MHAクラスタエラーサマリーの構築
-
[解決済み] ストアドプロシージャ 'dbo.aspnet_CheckSchemaVersion' が見つかりませんでした。
-
[解決済み] SQLのカラム名があいまいな場合のクエリエラー
-
[解決済み] SQL Server で複数行のテキストを 1 つのテキスト文字列に連結する方法
-
[解決済み] 各GROUP BYグループの最初の行を選択しますか?
-
[解決済み] SQLのSELECTでIF...THENを実行するにはどうすればよいですか?
-
[解決済み] UNIONとUNION ALLの違いは何ですか?
-
[解決済み] PostgreSQLからのPL/pgSQL出力をCSVファイルに保存する
-
[解決済み] SQLのインデックスとは何ですか?
-
[解決済み] SQL Serverで、ある日付より大きいすべての日付を照会するにはどうすればよいですか?