読者です 読者をやめる 読者になる 読者になる

N行のデータを「区切り文字を使って1列1行」にして返すクエリ

大分前にこんなの書いてました
1列N行のデータを「区切り文字を使って1列1行」にして返すアドホックなクエリ - お だ のスペース
が、Oracle で良いのを見つけました。

LISTAGG(集計関数) - オラクル・Oracle SQL 関数リファレンス
11gR2 から使える LISTAGG で実現できるようです。

Oracle だけではアレなので SQL Server のも紹介します。
カラムの値からカンマ区切り (CSV) の文字列を生成する - SQL Server 入門
XML型を経由するのは思いつかなかったですね~。

2014/12/23追記:
コメントにて教えてもらいました。LISTAGG より XMLAGG の方が良いようです。
Listagg function excdding 4000 characters | Oracle Community
LISTAGG だと 4000バイト超えるとエラーが出ますが、XMLAGG だと大丈夫でした。

select
  -- listagg(id, ',') within group (order by id) LISTAGG はエラーが出る
  rtrim(xmlagg(xmlelement(e,id,',').extract('//text()') order by id).GetClobVal(),',')
  , length(rtrim(xmlagg(xmlelement(e,id,',').extract('//text()') order by id).GetClobVal(),','))
 from (select level as id from dual connect by level < 1050)

ちなみに SQL Server 版では 4000バイト超えでも大丈夫でした。

with cte as (
  select 1 as id union all select id + 1 
  from cte 
  where id < 1050
)
select 
  replace((select id as [data()] from cte for xml path('')), ' ', ',') 
  , len(replace((select id as [data()] from cte for xml path('')), ' ', ','))
option (maxrecursion 0) 

[data()] って何?っと思ったのでリファレンス貼っときます。
パスを data() として指定した列の名前