SQL Server で文字列を全部結合したいだけなら
以下のように記述すれば出来るっぽい。
DECLARE @str AS varchar(max); SET @str = ''; SELECT @str = @str + str FROM SomeTable; SELECT @str;
参考:文字列を集計的に結合する(ユーザー定義関数経由で GROUP BY 対応)
カンマ区切りがしたければ、
DECLARE @str AS varchar(max); SET @str = ''; SELECT -- 先頭要素にはカンマを付けない @str = CASE @str WHEN '' THEN str ELSE @str + ', ' + str END FROM SomeTable ; SELECT @str;
とか。
でも
これはあくまで対象全部を結合するのであって、例えば、
n | str |
---|---|
1 | hoge |
1 | piyo |
2 | foo |
2 | bar |
みたいなテーブルを、
n | strs |
---|---|
1 | hoge, piyo |
2 | foo, bar |
のように GROUP BY することは出来ない*1。
SomeTable が n 順にソートされてることが前提で、
DECLARE @str AS varchar(max); SET @str = ''; DECLARE @n AS int; -- ありえない数値を入れておく SET @n = -1; SELECT -- nが変わるタイミングで@strをリセット @str = CASE @n WHEN n THEN @str ELSE '' END , @str = CASE @str WHEN '' THEN str ELSE @str + ', ' + str END -- @nの更新 , @n = n FROM SomeTable ; SELECT @n, @str;
こうすれば、
n | str |
---|---|
2 | foo, bar |
は出せる*2し、@str には途中、「hoge, piyo」も入るから、あと何ひねりかすれば出来るのかもしれない。
つか、T-SQL 独自の機能使ってるんだから、これでいいじゃん、とか思わなくも無いけどね。
-- 結果格納用のテーブル変数 DECLARE @Strs AS TABLE(n int, str varchar(max)); -- nの個数 DECLARE @count AS int; SELECT @count = COUNT(DISTINCT n) FROM SomeTable; DECLARE @i AS int; SET @i = 0; WHILE @i < @count BEGIN DECLARE @str AS varchar(max); SET @str = ''; -- nが@i + 1の文字列を結合 SELECT @str = CASE @str WHEN '' THEN str ELSE @str + ', ' + str END FROM SomeTable WHERE n = @i + 1 ; -- @i + 1と共に結合した文字列を格納 INSERT INTO @Strs VALUES(@i + 1, @str); SET @i = @i + 1; END -- 全部出力 SELECT * FROM @Strs;
n が 1 から連続してない場合、
DECLARE @Strs AS TABLE(n int, str varchar(max)); -- 連番とnの対応表 DECLARE @Ns AS TABLE(i int identity(0, 1), n int); DECLARE @count AS int; SELECT @count = COUNT(DISTINCT n) FROM SomeTable; -- iは自動採番して、nはSomeTableから取ってくる INSERT INTO @Ns(n) SELECT DISTINCT n FROM SomeTable ; DECLARE @i AS int; SET @i = 0; WHILE @i < @count BEGIN -- @iに対応するnを格納 DECLARE @n AS int; SELECT @n = n FROM @Ns WHERE i = @i; DECLARE @str AS varchar(max); SET @str = ''; SELECT @str = CASE @str WHEN '' THEN str ELSE @str + ', ' + str END FROM SomeTable WHERE n = @n ; INSERT INTO @Strs VALUES(@n, @str); SET @i = @i + 1; END SELECT * FROM @Strs;
CLR ユーザー定義集計関数なんてものもあるみたいだけど、正直、おおげさすぎるというかなんと言うか・・・
でもやっぱり FOLD 欲しい。