【SQL】分析関数のOVER句を使ってデータを集計する


SQLで集計を行う際に、行を束ねるのではなくて、全ての行に追加で集計結果のデータを持たせたい場合はありませんか?

指定したカラムごとで行を束ねたい場合はGROUP BY句を使えば実現できますが、行を束ねずに集計したい場合は別の方法を用いる必要があります。

それが、今回紹介する分析関数のOVER句です。

本記事では分析関数とは何かから始まり、OVER句の具体的な使い方まで解説します。

分析関数とは

SQLの分析関数は、グルーピングされたデータの集計結果を一つ一つの行に持たせることができる文法です。

集約関数との違い

分析関数はグルーピングされたデータに対して処理をするという点において、SUMCOUNTのような集約関数と考え方は似ています。

集約関数との決定的な違いは、集約関数は同一の値を持つ行をグルーピングして結果を取得するという点です。例えば、下記の図のようにCOUNT関数を用いてaddressごとの数をカウントしようとすると、同じaddressの値を持つ行はグルーピングされます。

一方で、分析関数は行ごとで集計したデータを取得できます。下記の図のように、行の数は変わらないままCOUNT関数の結果を取得することができるのです。

では次に、分析関数を実現するためのクエリの書き方を見ていきましょう。

SQLのOVER句とは

SQLで分析関数を使用するにはOVER句を使います。

OVER句を使った基本フォーマットが以下になります。

SQL
OVER (PARTITION BY カラム名 ORDER BY カラム名)

PARTITION BY

PARTITION BYGROUP BYのようなイメージで、指定した列でグルーピングを行います。GROUP BYはクエリ全体に対してグルーピングを行いますが、PARTITION BYは特定の列に対してのみ処理が行えます。

先ほどの例のように、addressごとの人数をカウントして各行にその結果を持たせたい場合は、下記のようなクエリを書きます。

SQL
COUNT(*) OVER (PARTITION BY address)

ORDER BY

ORDER BYは並び替えを行うことができる文法です。OVER句の中でもORDER BYを使うことができます。集計結果を並び替えたい場合はORDER BYも併せて使いましょう。

例えば、集計結果が多い順に並べ替えたい場合は、下記のようにORDER BYを指定するといった具合です。

SQL
COUNT(*) OVER (PARTITION BY address ORDER BY COUNT(*) DESC)

OVER句を使ってクエリを作成してみよう

ここからは具体的な使用例を見て、理解を深めていきましょう。

まずは、サンプルデータとして以下のusersテーブルを用意します。

サンプルデータ

idnameageaddress
1山田25東京都
2鈴木34神奈川県
3佐藤28神奈川県
4大野46大阪府
5小池56東京都
6近藤24東京都
7佐々木38大阪府
8宮田32福岡県
9田中51大阪府
10木村28神奈川県
usersテーブル

お題

usersテーブルに新しいカラム(avg_age_by_address)を作成して、都道府県ごとの平均年齢を追加してください

クエリ

SQL
SELECT
  id,
  name,
  address,
  age,
  AVG(age) OVER (PARTITION BY address) AS avg_age_by_address
FROM users
ORDER BY id ASC;

ポイントは6行目です。

まず、平均年齢を求めるAVG関数を使用して、AVG(age)とします。加えて、今回は都道府県ごとの平均年齢を算出する必要があるため、OVER句PARTITION BYを使って都道府県でグルーピングします。

この時、GROUP BY句を使ってしまうとクエリ全体でグルーピングされてしまうため、AVG(age)に対してのみ処理ができるOVER句を使います。

これによって、全ての行に対して都道府県ごとの平均年齢を持たせるカラムを作成することができました。

実行結果

idnameaddressageavg_age_by_address
1山田東京都2535
2鈴木神奈川県3430
3佐藤神奈川県2830
4大野大阪府4645
5小池東京都5635
6近藤東京都2435
7佐々木大阪府3845
8宮田福岡県3232
9田中大阪府5145
10木村神奈川県2830

avg_age_by_addressカラムが新規作成され、全ての行において都道府県別の平均年齢を取得することができました。

内容のまとめ

  • SQLの分析関数とはグルーピングされたデータの集計結果を一つ一つの行に持たせることができる文法
  • 集約関数は同一の値を持つ行をグルーピングした結果を取得しますが、分析関数も併用することで、全ての行に対してグルーピングした結果を取得できるようになる
  • SQLの分析関数にはOVER句を用いる
  • OVER句を使った基本フォーマットはOVER (PARTITION BY カラム名 ORDER BY カラム名)