トップページに戻る
次のSQLパズルへ
前のSQLパズルへ
9-1 複数行を1行に変換
SQLパズル
Namesテーブル
name
-------
Al
Ben
Charlie
David
Ed
Frank
Greg
Howard
Ida
Joe
Ken
Larry
Mike
Namesテーブルのname列を
5行ごとに、1行で表示する(最終行の余った列は、nullとする)
出力順は、行も列も、Namesテーブルのname列の昇順とする。
出力例(2行を1行に変換)
name1 name2
------- ------
Al Ben
Charlie David
Ed Frank
Greg Howard
Ida Joe
Ken Larry
Mike null
出力例(3行を1行に変換)
name1 name2 name3
----- ------ -------
Al Ben Charlie
David Ed Frank
Greg Howard Ida
Joe Ken Larry
Mike null null
出力例(4行を1行に変換)
name1 name2 name3 name4
----- ----- ------- ------
Al Ben Charlie David
Ed Frank Greg Howard
Ida Joe Ken Larry
Mike null null null
出力例(5行を1行に変換)
name1 name2 name3 name4 name5
----- ----- ------- ----- -----
Al Ben Charlie David Ed
Frank Greg Howard Ida Joe
Ken Larry Mike null null
SQLパズル 第2版のパズル62 [レポートの整形] を参考にさせていただきました
データ作成スクリプト
create table Names(name char(10) primary key);
insert into Names values('Al');
insert into Names values('Ben');
insert into Names values('Charlie');
insert into Names values('David');
insert into Names values('Ed');
insert into Names values('Frank');
insert into Names values('Greg');
insert into Names values('Howard');
insert into Names values('Ida');
insert into Names values('Joe');
insert into Names values('Ken');
insert into Names values('Larry');
insert into Names values('Mike');
SQL
--■■■window関数を使う方法■■■
select
max(case rn%5 when 0 then name end) as name1,
max(case rn%5 when 1 then name end) as name2,
max(case rn%5 when 2 then name end) as name3,
max(case rn%5 when 3 then name end) as name4,
max(case rn%5 when 4 then name end) as name5
from (select name,
-1+Row_Number() over(order by name) as rn
from Names) a
group by rn/5
order by rn/5;
--■■■window関数を使わない方法■■■
select
max(case rn%5 when 0 then name end) as name1,
max(case rn%5 when 1 then name end) as name2,
max(case rn%5 when 2 then name end) as name3,
max(case rn%5 when 3 then name end) as name4,
max(case rn%5 when 4 then name end) as name5
from (select name,
(select count(*)
from Names b
where b.name < a.name) as rn
from Names a) c
group by rn/5
order by rn/5;
解説
-1+Row_Number() over(order by name)として、C言語やJavaの配列の感覚で考えてます。
PostgreSQLの/演算子による整数型/整数型
は、C言語やJavaの/演算子と同じように、小数以下を切り捨てます。
int i=9;
i/=5; // iは1です(小数以下を切り捨て)
9.3. 算術関数と演算子
OracleSQLパズル 9-1 複数行を1行に変換