トップページに戻る
次のSQLパズルへ
前のSQLパズルへ
2-3-5 モード(最頻値)を取得
SQLパズル
最頻値テーブル
Col1
----
10
20
20
30
30
30
40
40
40
40
50
50
50
50
60
60
60
60
最頻値テーブルの、
Col1の最頻値(最も多く存在する値)と、
最頻値のレコード数を取得する。
出力結果
最頻値 最頻値のレコード数
------ ------------------
40 4
50 4
60 4
データ作成スクリプト
create table 最頻値テーブル(Col1 number(2));
insert into 最頻値テーブル values(10);
insert into 最頻値テーブル values(20);
insert into 最頻値テーブル values(20);
insert into 最頻値テーブル values(30);
insert into 最頻値テーブル values(30);
insert into 最頻値テーブル values(30);
insert into 最頻値テーブル values(40);
insert into 最頻値テーブル values(40);
insert into 最頻値テーブル values(40);
insert into 最頻値テーブル values(40);
insert into 最頻値テーブル values(50);
insert into 最頻値テーブル values(50);
insert into 最頻値テーブル values(50);
insert into 最頻値テーブル values(50);
insert into 最頻値テーブル values(60);
insert into 最頻値テーブル values(60);
insert into 最頻値テーブル values(60);
insert into 最頻値テーブル values(60);
commit;
SQL
--■■■集合関数のネストを使う方法■■■
select Col1 as 最頻値,count(*) as 最頻値のレコード数 from 最頻値テーブル
group by Col1
having count(*) = (select max(count(*)) from 最頻値テーブル group by Col1);
--■■■allを使う方法■■■
select Col1 as 最頻値,count(*) as 最頻値のレコード数 from 最頻値テーブル
group by Col1
having count(*) >= all(select count(*) from 最頻値テーブル group by Col1);
--■■■分析関数を使う方法■■■
select Col1,最頻値のレコード数
from (select Col1,
count(*) as レコード数,
max(count(*)) over() as 最頻値のレコード数
from 最頻値テーブル
group by Col1)
where レコード数 = 最頻値のレコード数
order by Col1;
--■■■stats_mode関数を使う方法(10g以降)■■■
select
(select stats_mode(Col1) from 最頻値テーブル) as 最頻値,
(select max(count(*)) from 最頻値テーブル group by Col1) as 最頻値のレコード数
from dual;
--■■■stats_mode関数を使う方法(10g以降)■■■
select 最頻値,最頻値のレコード数 from
(select stats_mode(Col1) as 最頻値 from 最頻値テーブル),
(select max(count(*)) as 最頻値のレコード数 from 最頻値テーブル group by Col1);
解説
having句で、最も多く存在する値かをチェックする方法や、
分析関数を使う方法や、stats_mode関数を使う方法があります
allを使う方法では、最初のクエリの、射影を返すクエリを、all述語の引数で使ってます。
マニュアルによると、stats_mode関数は、最頻値が複数あった時に任意の1つしか返さないそうです。
また、stats_mode関数は、集合関数の特性として、null値を無視します。
SQL> with WorkView as (
2 select 1 as ID,null as Val from dual
3 union all select 1,null from dual
4 union all select 1,null from dual
5 union all select 1,50 from dual
6 union all select 1,50 from dual
7 union all select 1,30 from dual)
8 select STATS_MODE(Val)
9 from WorkView
10 group by ID;
STATS_MODE(VAL)
---------------
50
マニュアル(stats_mode関数)(英語)
マニュアル(stats_mode関数)
CodeZine:HAVING句の力
CodeZine:分析関数の衝撃(前編)