1. ホーム
  2. sql

[解決済み] Microsoft SQL Server 2005でgroup_concat MySQL関数をシミュレートする?

2022-03-15 21:58:33

質問

MySQLベースのアプリケーションをMicrosoft SQL Server 2005に移行しようとしています(選択したわけではありませんが、それが人生です)。

元のアプリでは ほとんど 完全に ANSI-SQL 準拠のステートメントですが、ひとつだけ重要な例外があります -- MySQL の group_concat を頻繁に使っています。

group_concat 例えば、社員名とプロジェクト名からなるテーブルがある場合、以下のようなことが可能です。

SELECT empName, projID FROM project_members;

を返します。

ANDY   |  A100
ANDY   |  B391
ANDY   |  X010
TOM    |  A100
TOM    |  A510

...そして、group_concatを使うとこんな感じです。

SELECT 
    empName, group_concat(projID SEPARATOR ' / ') 
FROM 
    project_members 
GROUP BY 
    empName;

を返します。

ANDY   |  A100 / B391 / X010
TOM    |  A100 / A510

そこで、私が知りたいのは の機能をエミュレートするユーザー定義関数をSQL Serverで書くことは可能でしょうか? group_concat ?

UDFやストアドプロシージャなどの使用経験はほとんどなく、ストレートなSQLだけなので、あまり説明しすぎないようにお願いします :)

どのように解決するのですか?

本当に簡単な方法はありません。しかし、たくさんのアイデアがあります。

私が見つけたベストワン :

SELECT table_name, LEFT(column_names , LEN(column_names )-1) AS column_names
FROM information_schema.columns AS extern
CROSS APPLY
(
    SELECT column_name + ','
    FROM information_schema.columns AS intern
    WHERE extern.table_name = intern.table_name
    FOR XML PATH('')
) pre_trimmed (column_names)
GROUP BY table_name, column_names;

または、データに次のような文字が含まれていても正しく動作するバージョンもあります。 <

WITH extern
     AS (SELECT DISTINCT table_name
         FROM   INFORMATION_SCHEMA.COLUMNS)
SELECT table_name,
       LEFT(y.column_names, LEN(y.column_names) - 1) AS column_names
FROM   extern
       CROSS APPLY (SELECT column_name + ','
                    FROM   INFORMATION_SCHEMA.COLUMNS AS intern
                    WHERE  extern.table_name = intern.table_name
                    FOR XML PATH(''), TYPE) x (column_names)
       CROSS APPLY (SELECT x.column_names.value('.', 'NVARCHAR(MAX)')) y(column_names)