SSブログ

SQL分析関数 CUME_DISTとCOUNT OVER SQLポケリ [SQLポケリ]

本日もSQL分析関数である。

本日は、予定していた通り、CUME_DISTを紹介したい。
マニュアルを見ると、CUME_DISTは、累積分布を計算する分析関数、と書いてある。

はーん、わかったようなわからないような。

また、CUME_DISTは0〜1.0の範囲で値を戻す、とも書いてある。

なるほど、パーセンタイル値と同じか。
じゃあ、PERCENT_RANKと同じじゃない?とも思ってみたが、そうでもないみたい。
比較してみた。

-- PERCENT_RANK

SELECT val, PERCENT_RANK() OVER (ORDER BY val)
 FROM test_analyze3;

val  PRNK
---- ----
   1    0   -- {1}          0/4 0.0
   2 0.25   -- {1,2}        1/4 0.25
   3  0.5   -- {1,2,3}      2/4 0.5
   3  0.5   -- {1,2,3,3}    2/4 0.5
   4    1   -- {1,2,3,3,4}  4/4 1.0


-- CUME_DIST

SELECT val, CUME_DIST() OVER (ORDER BY val)
 FROM test_analyze3;

val  CDST
---- ----
   1  0.2   -- {1}          1/5 0.2
   2  0.4   -- {1,2}        2/5 0.4
   3  0.8   -- {1,2,3}      4/5 0.8
   3  0.8   -- {1,2,3,3}    4/5 0.8
   4    1   -- {1,2,3,3,4}  5/5 1.0


計算式の違いは、以下のようになる。
PERCENT_RANKは、RANK-1 / 全体の個数-1
CUME_DISTは、集合の個数 / 全体の個数

分子の方は微妙に異なる。分母の方は、全体の個数を-1するかどうかの違いである。

これだけでCUME_DISTの解説はおしまい。というのも寂しいので、解説していないPARTITION BYについても書いてみたいと思う。

PARTITION BY

分析関数は、OVER句で順序を指定する必要がある。これまでの例では、ORDER BYで順序のみを指定していたのだが、ここにPARTITION BYでグループ化の方法を指定できる。
グループ分けできるサンプルデータを作成して、PARTITION BYをやってみよう。

CREATE TABLE test_analyze5 (
 type INTEGER,
 val INTEGER
);

INSERT INTO test_analyze5 VALUES(1, 1);
INSERT INTO test_analyze5 VALUES(1, 2);
INSERT INTO test_analyze5 VALUES(1, 3);
INSERT INTO test_analyze5 VALUES(1, 4);
INSERT INTO test_analyze5 VALUES(2, 1);
INSERT INTO test_analyze5 VALUES(2, 1);
INSERT INTO test_analyze5 VALUES(2, 2);
INSERT INTO test_analyze5 VALUES(2, 3);
INSERT INTO test_analyze5 VALUES(2, 4);

SELECT type, val,
  CUME_DIST() OVER (PARTITION BY type ORDER BY val) CUME
 FROM test_analyze5
 ORDER BY type, val;

type val  CUME
---- ---- ----
   1    1 0.25
   1    2  0.5
   1    3 0.75
   1    4    1
   2    1  0.4
   2    1  0.4
   2    2  0.6
   2    3  0.8
   2    4    1


PARTITION BYは、OVER句のカッコの中に記述する。ORDER BYは必須だが、PARTITION BYは任意。順番は、PARTITION BY、ORDER BYの順に書く必要がある。SELECT命令でのGROUP BYとORDER BYの関係と同じなので覚えやすいと思う。
PARTITION BYのグループ化指定方法も、GROUP BYと同じ。例では、type列の値別にグループ化してみた。

type val  CUME
---- ---- ----
   1    1 0.25  -+
   1    2  0.5   +- type=1のグループ
   1    3 0.75   |
   1    4    1  -+
   2    1  0.4  -+
   2    1  0.4   |
   2    2  0.6   +- type=2のグループ
   2    3  0.8   |
   2    4    1  -+


PARTITION BYを省略すると、全体が一つのグループになる。
例では、type列の値別にPARTITION BYしている。type=1とtype=2の二つのグループに分けられ、その中でvalの値が昇順で並び替えられていることがわかる。

COUNT OVER

さて、ここまでは分析関数に対してOVER句を指定して、どういった計算が行われるのかを紹介してきた。実は、従来からある、集計関数もOVER句を付けて分析関数のように使うこともできる。
その例として、COUNT関数をOVER句付きで使ってみよう。上記のCUME_DISTの例では、type=1のグループとtype=2のグループで行数が異なっていた。これをCOUNT関数で計算してみよう。

SELECT type, val,
  CUME_DIST() OVER (PARTITION BY type ORDER BY val) CUME,
  COUNT(*) OVER (PARTITION BY type) CONT
 FROM test_analyze5
 ORDER BY type, val;

type val  CUME CONT
---- ---- ---- ----
   1    1 0.25    4
   1    2  0.5    4
   1    3 0.75    4
   1    4    1    4
   2    1  0.4    5
   2    1  0.4    5
   2    2  0.6    5
   2    3  0.8    5
   2    4    1    5


COUNTは集計関数である。OVERを付けなければ、集計関数なので、SELECT命令にGROUP BYを付けて使用することが多いと思う。しかし、OVER句を付けて、分析関数として使えば、グループ化の方法は、OVER句のPARTITION BYの内容で決定できる。
COUNTで個数を集計するにあたり、データの並び順は重要ではなく、必要のない情報であるため、「ORDER BYを省略できる」。一方、順番に並べることで計算を行っていた分析関数では、ORDER BYを省略することはできない。
PARTITION BYはグループ化の必要がなければ、COUNTでも省略可能である。

では、COUNTのOVER句でORDER BYを指定しても意味のないものとなり、無視されるのであろうか?ちょっとやってみることにする。

SELECT type, val,
  CUME_DIST() OVER (PARTITION BY type ORDER BY val) CUME,
  COUNT(*) OVER (PARTITION BY type ORDER BY val) CNTO,
  COUNT(*) OVER (PARTITION BY type) CONT
 FROM test_analyze5
 ORDER BY type, val;

type val  CUME CNTO CONT
---- ---- ---- ---- ----
   1    1 0.25    1    4
   1    2  0.5    2    4
   1    3 0.75    3    4
   1    4    1    4    4
   2    1  0.4    2    5
   2    1  0.4    2    5
   2    2  0.6    3    5
   2    3  0.8    4    5
   2    4    1    5    5


おー、予想に反して「無視されることはない」ようである。CNTOの列が、ORDER BY付きである。ORDER BYを付けることで、分析関数に渡される集合が、処理しているカレント行までとなる。
CNTO/CONTでCUME_DISTが計算できている。あー、そういうことか。

ここでは、COUNTの例を紹介したが、集計関数のSUM、AVG、MIN、MAXでもOVER句を使って分析関数のように使用することができる。

本日はここまで。





サイト内を検索

タグ:分析関数 SQL
nice!(1)  コメント(0) 
共通テーマ:携帯コンテンツ

nice! 1

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。



Copyright Atsushi Asai Google+朝井淳
[改訂第4版]SQLポケットリファレンス

[改訂第4版]SQLポケットリファレンス

  • 作者: 朝井 淳
  • 出版社/メーカー: 技術評論社
  • 発売日: 2017/02/18
  • メディア: 単行本(ソフトカバー)

イラストで理解 SQL はじめて入門

イラストで理解 SQL はじめて入門

  • 作者: 朝井 淳
  • 出版社/メーカー: 技術評論社
  • 発売日: 2019/05/16
  • メディア: 単行本(ソフトカバー)

[データベースの気持ちがわかる]SQLはじめの一歩 (WEB+DB PRESS plus)

[データベースの気持ちがわかる]SQLはじめの一歩 (WEB+DB PRESS plus)

  • 作者: 朝井 淳
  • 出版社/メーカー: 技術評論社
  • 発売日: 2015/03/03
  • メディア: 単行本(ソフトカバー)

Access クエリ 徹底活用ガイド ~仕事の現場で即使える

Access クエリ 徹底活用ガイド ~仕事の現場で即使える

  • 作者: 朝井 淳
  • 出版社/メーカー: 技術評論社
  • 発売日: 2018/05/25
  • メディア: 大型本

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。