トップページに戻る
次のSQLパズルへ
前のSQLパズルへ
3-22 相関サブクエリで順位付け
SQLパズル
Testテーブル
科目 点数
---- ----
英語 90
英語 90
英語 90
英語 80
英語 80
英語 70
数学 90
数学 80
数学 70
数学 70
数学 60
数学 60
科目ごとに順位を付けて出力する。
出力結果
科目 点数 Rank dense_Rank Row_Number
---- ---- ---- ---------- ----------
英語 90 1 1 1
英語 90 1 1 2
英語 90 1 1 3
英語 80 4 2 4
英語 80 4 2 5
英語 70 6 3 6
数学 90 1 1 1
数学 80 2 2 2
数学 70 3 3 3
数学 70 3 3 4
数学 60 5 4 5
数学 60 5 4 6
データ作成スクリプト
create table Test(
科目 char(4),
点数 number(2));
insert into Test values('英語',90);
insert into Test values('英語',90);
insert into Test values('英語',90);
insert into Test values('英語',80);
insert into Test values('英語',80);
insert into Test values('英語',70);
insert into Test values('数学',90);
insert into Test values('数学',80);
insert into Test values('数学',70);
insert into Test values('数学',70);
insert into Test values('数学',60);
insert into Test values('数学',60);
commit;
SQL
--■■■相関サブクエリを使う方法■■■
select 科目,点数,
(select count(*)+1
from Test b
where b.科目 = a.科目
and b.点数 > a.点数) as "Rank",
(select count(distinct b.点数)+1
from Test b
where b.科目 = a.科目
and b.点数 > a.点数) as "dense_Rank",
(select count(*)+1
from Test b
where b.科目 = a.科目
and (b.点数 > a.点数 or b.点数 = a.点数 and b.RowID > a.RowID)) as "Row_Number"
from Test a
order by 科目,"Row_Number";
--■■■分析関数を使う方法■■■
select 科目,点数,
Rank() over(partition by 科目 order by 点数 desc) as "Rank",
dense_Rank() over(partition by 科目 order by 点数 desc) as "dense_Rank",
Row_Number() over(partition by 科目 order by 点数 desc) as "Row_Number"
from Test
order by 科目,"Row_Number";
解説
相関サブクエリで、Rank関数、dense_Rank関数、Row_Number関数
を模倣できます。
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
自己結合とhavingを使って、
Rank,dense_Rank,Row_Number
が3のデータを出力する方法は、下記となります。
SQL> select a.科目,a.点数
2 from test a,test b
3 where a.科目 = b.科目
4 and a.点数 < b.点数
5 group by a.科目,a.点数,a.RowID
6 having count(*)+1 = 3
7 order by a.科目,a.点数;
科目 点数
---- ----
数学 70
数学 70
SQL> select a.科目,a.点数
2 from test a,test b
3 where a.科目 = b.科目
4 and a.点数 < b.点数
5 group by a.科目,a.点数,a.RowID
6 having count(distinct b.点数)+1 = 3
7 order by a.科目,a.点数;
科目 点数
---- ----
英語 70
数学 70
数学 70
SQL> select a.科目,a.点数
2 from test a,test b
3 where a.科目 = b.科目
4 and (a.点数 < b.点数 or a.点数 = b.点数 and a.RowID < b.RowID)
5 group by a.科目,a.点数,a.RowID
6 having count(*)+1 = 3
7 order by a.科目,a.点数;
科目 点数
---- ----
英語 90
数学 70
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
3-4 順位にupdate
3-5 順位(DENSE)が指定した範囲のデータを取得
7-14 古のSQL(順位付け)