トップページに戻る
次のSQLパズルへ
前のSQLパズルへ
10-188 連続してなかったらインクリメント
SQLパズル
VerTable
Name SortKey
----- -------
Name1 10
Name1 20
Name1 30
Name1 40
Name2 50
Name2 60
Name1 70
Name1 80
Name3 90
Name2 100
Name1 110
Name1 120
Name4 130
SortKeyの昇順で、Nameを元にversionを求める。
Nameが最低でも1回違うNameになって、また同じNameになったらバージョンがインクリメントされます。
出力結果
Name SortKey version
----- ------- -------
Name1 10 1
Name1 20 1
Name1 30 1
Name1 40 1
Name2 50 1
Name2 60 1
Name1 70 2
Name1 80 2
Name3 90 1
Name2 100 2
Name1 110 3
Name1 120 3
Name4 130 1
データ作成スクリプト
create table VerTable as
select 'Name1' as Name,10 as SortKey from dual
union select 'Name1', 20 from dual
union select 'Name1', 30 from dual
union select 'Name1', 40 from dual
union select 'Name2', 50 from dual
union select 'Name2', 60 from dual
union select 'Name1', 70 from dual
union select 'Name1', 80 from dual
union select 'Name3', 90 from dual
union select 'Name2',100 from dual
union select 'Name1',110 from dual
union select 'Name1',120 from dual
union select 'Name4',130 from dual;
SQL
--■■■旅人算の感覚を使う方法■■■
select Name,SortKey,
dense_rank() over(partition by Name order by PartID) as version
from (select Name,SortKey,
Row_Number() over(order by SortKey)
- Row_Number() over(partition by Name order by SortKey) as PartID
from VerTable)
order by SortKey;
--■■■旅人算の感覚を使わない方法(10g以降)■■■
select Name,SortKey,
sum(willSum) over(partition by Name order by SortKey) as version
from (select Name,SortKey,
case when lnnvl(Name = Lag(Name) over(order by SortKey))
then 1 else 0 end as willSum
from VerTable)
order by SortKey;
--■■■旅人算の感覚を使わない方法■■■
select Name,SortKey,
sum(willSum) over(partition by Name order by SortKey) as version
from (select Name,SortKey,
case when Name = Lag(Name) over(order by SortKey)
then 0 else 1 end as willSum
from VerTable)
order by SortKey;
解説