トップページに戻る
次のSQLパズルへ
前のSQLパズルへ
2-3-33 文字列の中央値(メジアン)のような値
SQLパズル
文字列の中央値(メジアン)のような値を求める。
5個の場合は、3番目
stringMedianFiveテーブル
Val
---
AAA
AAB
ABB ← 出力対象
CAA
EAA
6個の場合も、3番目
stringMedianSixテーブル
Val
---
AAA
AAB
ABB ← 出力対象
CAA
EAA
FGH
データ作成スクリプト
create table stringMedianFive(Val) as
select 'AAAXX' from dual union
select 'AABXX' from dual union
select 'ABBXX' from dual union
select 'CAAXX' from dual union
select 'EAAXX' from dual;
create table stringMedianSix(Val) as
select 'AAAYY' from dual union
select 'AABYY' from dual union
select 'ABBYY' from dual union
select 'CAAYY' from dual union
select 'EAAYY' from dual union
select 'FGHYY' from dual;
SQL
--■■■分析関数を使う方法(10g以降)■■■
select Val as medianVal
from (select Val,Rn,median(Rn) over() as medianRn
from (select Val,Row_Number() over(order by Val) as Rn
from stringMedianFive))
where Rn = floor(medianRn);
select Val as medianVal
from (select Val,Rn,median(Rn) over() as medianRn
from (select Val,Row_Number() over(order by Val) as Rn
from stringMedianSix))
where Rn = floor(medianRn);
--■■■標準SQLを意識した方法■■■
select max(decode(Rn,ceil(RecordCount/2),Val)) as medianVal
from (select count(*) as RecordCount from stringMedianFive),
(select Val,(select count(*)+1
from stringMedianFive b
where b.Val < a.Val) as Rn
from stringMedianFive a);
select max(decode(Rn,ceil(RecordCount/2),Val)) as medianVal
from (select count(*) as RecordCount from stringMedianSix),
(select Val,(select count(*)+1
from stringMedianSix b
where b.Val < a.Val) as Rn
from stringMedianSix a);
解説
標準SQLを意識した方法では、
順位の最大値を2で割って切り上げた順位を持つ値を
求めてます。