トップページに戻る
次のSQLパズルへ
前のSQLパズルへ
10-315 最大値の行の各値を1行にまとめる
SQLパズル
PivTest
Name Val DT
-------- --- ----------
Personal 111 2010-03-11
Personal 999 2010-04-23
Personal 444 2010-05-29
Shared 555 2010-03-11
Shared 333 2010-04-25
NameがPersonalでDTが最大の行の各値と、
NameがSharedでDTが最大の行の各値を1行にまとめる。
出力結果
P_VAL P_NAME P_DT S_VAL S_NAME S_DT
----- -------- ---------- ----- ------ ----------
444 Personal 2010-05-29 333 Shared 2010-04-25
データ作成スクリプト
create table PivTest(Name,Val,DT) as
select 'Personal',111,date '2010-03-11' from dual union
select 'Personal',999,date '2010-04-23' from dual union
select 'Personal',444,date '2010-05-29' from dual union
select 'Shared' ,555,date '2010-03-11' from dual union
select 'Shared' ,333,date '2010-04-25' from dual;
SQL
--■■■max関数とdecode関数を組み合わせる方法■■■
select
max(Val) Keep(Dense_Rank Last order by decode(Name,'Personal',DT) nulls first) as Val,
max(decode(Name,'Personal',Name) as NAME,
max(decode(Name,'Personal',DT)) as DT,
max(Val) Keep(Dense_Rank Last order by decode(Name,'Shared',DT) nulls first) as SHARED_Val,
max(decode(Name,'Shared',Name) as SHARED_Name,
max(decode(Name,'Shared',DT)) as SHARED_DT
from PivTest;
--■■■Pivotを使う方法(11g以降)■■■
select *
from PivTest
pivot (max(Val) Keep(Dense_Rank Last order by DT) as Val,
max(Name) as Name,
max(dt) as dt
for Name in ('Personal' as P,'Shared' as S));
解説
この場合は、Pivotを使ったほうがシンプルだと思いますねぇ
max関数とdecode関数を組み合わせる方法で、
Keep指定して、nulls firstを使うのは、シンプルとは思えないので
10-278 unpivotとpivot