トップページに戻る
次のSQLパズルへ
前のSQLパズルへ
8-7 次の入社日を求める
SQLパズル
入社テーブル
名前 入社日
--------- --------
Scott 20001223
Tiger 20011012
Kim 20030401
Tom 20030401
Wendy 20030401
Joe 20030401
John 20040530
Hideyoshi 20040730
Ieyasu 20040730
Nobunaga 20040730
Mithuhide 20051230
それぞれの、
次に入社した人の、入社日を求める。
出力結果
名前 入社日 次の入社日
--------- -------- ----------
Scott 20001223 20011012
Tiger 20011012 20030401
Kim 20030401 20040530
Tom 20030401 20040530
Wendy 20030401 20040530
Joe 20030401 20040530
John 20040530 20040730
Hideyoshi 20040730 20051230
Ieyasu 20040730 20051230
Nobunaga 20040730 20051230
Mithuhide 20051230 null
SQLクックブックのレシピ8.7を参考にさせていただきました
データ作成スクリプト
create table 入社 as
select 'Scott' as 名前,20001223 as 入社日 from dual
union select 'Tiger',20011012 from dual
union select 'Kim',20030401 from dual
union select 'Tom',20030401 from dual
union select 'Wendy',20030401 from dual
union select 'Joe',20030401 from dual
union select 'John',20040530 from dual
union select 'Hideyoshi',20040730 from dual
union select 'Ieyasu',20040730 from dual
union select 'Nobunaga',20040730 from dual
union select 'Mithuhide',20051230 from dual;
SQL
--■■■分析関数を使う方法1■■■
select 名前,入社日,
Lead(入社日,RevRank) over(order by 入社日,名前) as 次の入社日
from (select 名前,入社日,
Row_Number() over(partition by 入社日 order by 名前 desc) as RevRank
from 入社);
--■■■分析関数を使う方法2■■■
select 名前,入社日,
max(入社日) over(order by Rank
range between 1 following
and 1 following) as 次の入社日
from (select 名前,入社日,
Dense_Rank() over(order by 入社日) as Rank
from 入社)
order by 入社日,名前;
--■■■分析関数を使う方法3■■■
select 名前,入社日,
min(入社日) over(order by 入社日
range between 1 following
and unbounded following) as 次の入社日
from 入社
order by 入社日,名前;
--■■■相関サブクエリを使う方法■■■
select 名前,入社日,
(select min(b.入社日)
from 入社 b
where b.入社日 > a.入社日) as 次の入社日
from 入社 a
order by 入社日,名前;
解説
分析関数を使う方法1では、逆ソートの考え方を使ってます。
SQLクックブックでは、Lead関数の引数に
件数 - 正順位 + 1
を指定してますが、
正順位 + 逆順位 = 件数 + 1
を移項すると
逆順位 = 件数 - 正順位 + 1
なので、同じ意味となります。
2-3-6 メジアン(中央値)を取得
2-3-24 逆ソート(リバースソート)
2-3-26 正順位と逆順位
分析関数を使う方法2のように、
Dense_Rank関数とrangeを組み合わせてもいいです。
分析関数を使う方法3であれば、
インラインビューは不要となります。
分析関数の衝撃3 (後編)
分析関数の衝撃6 (応用編)