トップページに戻る    次のSQLパズルへ    前のSQLパズルへ

7-53 グループ化とdecode関数

SQLパズル

履歴テーブル
Code  Val
----  ---
  10    3
  10    6
  20    9  ←出力対象
  20   12
  10   16  ←出力対象
  30   20  ←出力対象
  40   24  ←出力対象
  40   28
  40   30
  50   35
  60   40  ←出力対象
  50   45
  50   50  ←出力対象
  70   52
  80   54
  80   56
  70   58  ←出力対象
  80   60
  80   70  ←出力対象

履歴テーブルを、Valの昇順でソートして、
Codeごとの、Valが最小のデータを出力する
ただし、連続しない同一Codeがある場合には、Valが最大のデータを出力する


データ作成スクリプト

create table 履歴(
Code number(2),
Val  number(2));

insert into 履歴 values(10, 3);
insert into 履歴 values(10, 6);
insert into 履歴 values(20, 9);
insert into 履歴 values(20,12);
insert into 履歴 values(10,16);
insert into 履歴 values(30,20);
insert into 履歴 values(40,24);
insert into 履歴 values(40,28);
insert into 履歴 values(40,30);
insert into 履歴 values(50,35);
insert into 履歴 values(60,40);
insert into 履歴 values(50,45);
insert into 履歴 values(50,50);
insert into 履歴 values(70,52);
insert into 履歴 values(80,54);
insert into 履歴 values(80,56);
insert into 履歴 values(70,58);
insert into 履歴 values(80,60);
insert into 履歴 values(80,70);
commit;


SQL

--■■■旅人算の感覚を使う方法■■■
select Code,
case when count(distinct kyori) = 1
     then min(Val) else max(Val) end as Val
from (select Code,Val,
       Row_Number() over(order by Val)
      -Row_Number() over(partition by Code order by Val) as kyori
        from 履歴)
group by Code
order by Val;


解説

旅人算の感覚を使うといいでしょう。