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

10-21 ソート条件を他分岐

SQLパズル

商品テーブル
商品ID  商品名       単価    入荷日
------  ----------  ----   ----------
     1  あいうえお   100   2005/10/11
     2  かきくけこ   800   2005/10/12
     3  さしすせそ   350   2005/10/13
     4  たちつてと   500   2005/10/15
     5  なにぬねの   120   2005/10/15

商品テーブルをIN_SORT(定数)の値に応じて、
以下のようにソートして出力する。

IN_SORTが1の場合、order by 商品ID
IN_SORTが2の場合、order by 商品ID desc
IN_SORTが3の場合、order by 商品名,商品ID desc
IN_SORTが4の場合、order by 商品名 desc,商品ID desc
IN_SORTが5の場合、order by 単価,商品ID desc
IN_SORTが6の場合、order by 単価 desc,商品ID desc
IN_SORTが7の場合、order by 入荷日,商品ID desc
IN_SORTが8の場合、order by 入荷日 desc,商品ID desc


データ作成スクリプト

create table 商品(
商品ID number(1),
商品名 char(10),
単価   number(3),
入荷日 date);

insert into 商品 values(1,'あいうえお',100,to_date('20051011','YYYYMMDD'));
insert into 商品 values(2,'かきくけこ',800,to_date('20051012','YYYYMMDD'));
insert into 商品 values(3,'さしすせそ',350,to_date('20051013','YYYYMMDD'));
insert into 商品 values(4,'たちつてと',500,to_date('20051015','YYYYMMDD'));
insert into 商品 values(5,'なにぬねの',120,to_date('20051015','YYYYMMDD'));
commit;


SQL

def IN_SORT = 2

--■■■case式とRow_Number関数を使う方法■■■
select 商品ID,商品名,単価,
to_char(入荷日,'YYYY/MM/DD') as 入荷日
from 商品 a
order by
case &IN_SORT
when 1 then Row_Number() over(order by 商品ID)
when 2 then Row_Number() over(order by 商品ID desc)
when 3 then Row_Number() over(order by 商品名,商品ID desc)
when 4 then Row_Number() over(order by 商品名 desc,商品ID desc)
when 5 then Row_Number() over(order by 単価,商品ID desc)
when 6 then Row_Number() over(order by 単価 desc,商品ID desc)
when 7 then Row_Number() over(order by a.入荷日,商品ID desc)
when 8 then Row_Number() over(order by a.入荷日 desc,商品ID desc)
end;

--■■■decode関数を使う方法■■■
select 商品ID,商品名,単価,
to_char(入荷日,'YYYY/MM/DD') as 入荷日
from 商品 a
order by
decode(&IN_SORT,1,  商品ID)     ,
decode(&IN_SORT,2,  商品ID) desc,
decode(&IN_SORT,3,  商品名)     ,decode(&IN_SORT,3,商品ID) desc,
decode(&IN_SORT,4,  商品名) desc,decode(&IN_SORT,4,商品ID) desc,
decode(&IN_SORT,5,    単価)     ,decode(&IN_SORT,5,商品ID) desc,
decode(&IN_SORT,6,    単価) desc,decode(&IN_SORT,6,商品ID) desc,
decode(&IN_SORT,7,a.入荷日)     ,decode(&IN_SORT,7,商品ID) desc,
decode(&IN_SORT,8,a.入荷日) desc,decode(&IN_SORT,8,商品ID) desc;

--■■■decode関数とcase式を使う方法■■■
select 商品ID,商品名,単価,
to_char(入荷日,'YYYY/MM/DD') as 入荷日
from 商品 a
order by
decode(&IN_SORT,1,  商品ID),
decode(&IN_SORT,3,  商品名),
decode(&IN_SORT,4,  商品名) desc,
decode(&IN_SORT,5,    単価),
decode(&IN_SORT,6,    単価) desc,
decode(&IN_SORT,7,a.入荷日),
decode(&IN_SORT,8,a.入荷日) desc,
case when &IN_SORT in(2,3,4,5,6,7,8) then 商品ID end desc;


解説

case式とRow_Number関数を使う方法では、
ソート条件の違うRow_Number関数を用意して、
単純case式で、IN_SORTの値で他分岐させてます。

分析関数 について