トップページに戻る
次のSQLパズルへ
前のSQLパズルへ
8-55 次の入社日を求めるのアレンジ問題1
SQLパズル
ID sortKey Val
-- ------- ----
10 1 AAAA
10 2 FFFF
10 3 BBBB
20 5 GGGG
20 6 CCCC
20 8 HHHH
30 4 DDDD
30 5 IIII
40 4 EEEE
40 6 JJJJ
次のIDでsortKeyが最小の行のValを求める。
出力結果
ID sortKey Val nextVal
-- ------- ---- -------
10 1 AAAA GGGG
10 2 FFFF GGGG
10 3 BBBB GGGG
20 5 GGGG DDDD
20 6 CCCC DDDD
20 8 HHHH DDDD
30 4 DDDD EEEE
30 5 IIII EEEE
40 4 EEEE null
40 6 JJJJ null
SQLクックブックのレシピ8.7を参考にさせていただきました
データ作成スクリプト
create table dupLeadT(ID,sortKey,Val) as
select 10,1,'AAAA' from dual union all
select 10,2,'FFFF' from dual union all
select 10,3,'BBBB' from dual union all
select 20,5,'GGGG' from dual union all
select 20,6,'CCCC' from dual union all
select 20,8,'HHHH' from dual union all
select 30,4,'DDDD' from dual union all
select 30,5,'IIII' from dual union all
select 40,4,'EEEE' from dual union all
select 40,6,'JJJJ' from dual;
SQL
select ID,sortKey,Val,
Lead(Val,RevRank) over(order by ID,sortKey) as nextVal
from (select ID,sortKey,Val,
Row_Number() over(partition by ID order by sortKey desc) as RevRank
from dupLeadT)
order by ID,sortKey;
解説
Row_Number関数の結果を、Lead関数の引数に使用してます。
8-7 次の入社日を求める
ちなみに、次の次のIDでsortKeyが最小の行のValを求めるのであれば、
下記のようなSQLとなります。
select ID,sortKey,Val,
max(firVal) over(order by rn range between 2 following
and 2 following) as next2Val
from (select ID,sortKey,Val,
dense_rank() over(order by ID) as rn,
First_Value(Val) over(partition by ID order by sortKey) as firVal
from dupLeadT)
order by ID,sortKey;
ID sortKey Val next2Val
-- ------- ---- --------
10 1 AAAA DDDD
10 2 FFFF DDDD
10 3 BBBB DDDD
20 5 GGGG EEEE
20 6 CCCC EEEE
20 8 HHHH EEEE
30 4 DDDD null
30 5 IIII null
40 4 EEEE null
40 6 JJJJ null