1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【SQL初学者向け】GROUP BYと集計関数(MAX・SUM)の仕組みをスッキリ理解しよう!

1
Posted at

はじめに

SQLを書いていると、こんな疑問を持ったことはありませんか?

  • GROUP BY すると、データはどうまとめられるの?
  • MAXSUM は、それぞれ何をしているの?
  • MAX で同じ最大値が複数あったらどうなるの?
  • NULL が入っている場合、MAXSUM の結果はどうなるの?
  • NVL はなぜ使うの?

特に、

GROUP BY user_id

MAX(...)
SUM(...)

を組み合わせたSQLは、初学者にとって少し分かりづらい💦

そこで今回は、ECサイトの注文履歴を例にして、実際のデータがどのように集計されるのかを見ながら解説します。

この記事を読み終わるころには、

「GROUP BYでデータをグループ化して、MAXは最大値、SUMは合計値を返すんだ!」

というところまで理解できることを目指します。


この記事の対象読者

この記事は、以下のような方を対象にしています。

  • SQLを勉強し始めたばかりの方
  • SELECTWHERE は分かるけれど、GROUP BY がまだ苦手な方
  • MAXSUM などの集計関数を使ったSQLを理解したい方
  • NULLNVL の関係を知りたい方
  • 実際のデータを使ってSQLの動きを理解したい方

反対に、SQLの集計処理をすでに理解している方には、少し基本的な内容に感じるかもしれません。


1. まずは完成形のSQLを見てみよう

今回使用するSQLはこちらです。

SELECT 
     user_id
    ,MAX(NVL(shipping_fee, 0)) AS max_shipping_fee
    ,SUM(NVL(order_price, 0))   AS total_order_price
FROM 
    orders
GROUP BY 
    user_id;

一見すると、

MAX(NVL(shipping_fee, 0))

SUM(NVL(order_price, 0))

など、少し複雑に見えます。

しかし、1つずつ分解すると、それほど難しくありません。

このSQLでやっていることは、大きく分けて3つです。

  1. user_id ごとにデータをグループ化する
  2. グループ内の送料から最大値を取得する
  3. グループ内の購入金額を合計する

まずは、この3つを順番に見ていきましょう。


2. GROUP BYとは?

まず重要なのが GROUP BY です。

今回のSQLでは、

GROUP BY user_id

としています。

これは簡単にいうと、

同じ user_id のデータを1つのグループとしてまとめる

という処理です。

例えば、元データが以下のようになっていたとします。

集計前のデータ

user_id shipping_fee order_price
100 500 5,000
100 NULL 3,000
100 1,000 2,000
200 500 4,000
200 800 6,000

このデータに、

GROUP BY user_id

を指定すると、

user_id = 100 のグループ
user_id = 200 のグループ

というように、user_id ごとにグループが作られます。

イメージとしては、

100
├─ 500円
├─ NULL
└─ 1,000円

200
├─ 500円
└─ 800円

という状態です。

ここから、各グループに対して MAXSUM などの集計関数を使います。


3. MAXとは?

MAX は、

指定したグループの中から最大の値を返す

集計関数です。

基本的な書き方は以下です。

SELECT MAX(カラム名)
FROM テーブル名;

例えば、

SELECT MAX(shipping_fee)
FROM orders;

とすると、shipping_fee の中で最も大きい値を取得できます。


4. SUMとは?

一方、SUM は、

指定したグループの値を合計する

集計関数です。

例えば、

SELECT SUM(order_price)
FROM orders;

とすると、order_price の合計値を取得できます。

つまり、

関数 何をする?
MAX 最大値を返す
SUM 合計値を返す

と覚えておくと分かりやすいです。


5. GROUP BYとMAX・SUMを組み合わせるとどうなる?

ここまで分かったところで、最初のSQLをもう一度見てみましょう。

SELECT 
     user_id
    ,MAX(NVL(shipping_fee, 0)) AS max_shipping_fee
    ,SUM(NVL(order_price, 0))   AS total_order_price
FROM 
    orders
GROUP BY 
    user_id;

今回のポイントは、

GROUP BY user_id

でユーザーごとにグループを作り、そのグループに対して、

MAX(shipping_fee)

SUM(order_price)

を実行していることです。


6. 実際のデータで確認してみよう

例えば、user_id = 100 の注文データが3件あるとします。

user_id shipping_fee order_price
100 500 5,000
100 NULL 3,000
100 1,000 2,000

ここで、

GROUP BY user_id

を実行すると、3件のデータが「user_id = 100」という1つのグループとして扱われます。

そして、このグループに対して MAXSUM を実行します。


MAXの場合

送料は、

500
NULL
1,000

です。

今回は NVL(shipping_fee, 0) を使っているので、

500
0
1,000

として扱われます。

この中で最大の値は、

1,000

です。

そのため、

MAX(NVL(shipping_fee, 0))

の結果は、

1,000

になります。


SUMの場合

購入金額は、

5,000
3,000
2,000

です。

これらを合計すると、

5,000 + 3,000 + 2,000 = 10,000

となります。

そのため、

SUM(NVL(order_price, 0))

の結果は、

10,000

になります。


7. 集計結果はこうなる

ここまでの処理をまとめると、結果は以下のようになります。

user_id max_shipping_fee total_order_price
100 1,000 10,000

つまり、

  • GROUP BY → ユーザーごとにまとめる
  • MAX → そのユーザーの送料の最大値を取得
  • SUM → そのユーザーの購入金額を合計

という処理をしています。


8. MAXの値が重複したらどうなる?

ここで、初学者が疑問に思いやすいポイントです。

例えば、送料1,000円の注文がもう1件追加されたとします。

集計前のデータ

user_id shipping_fee order_price
100 500 5,000
100 NULL 3,000
100 1,000 2,000
100 1,000 4,000

送料だけを見ると、

500
NULL → 0
1,000
1,000

です。

この中で最大の値は、

1,000

です。

そのため、

MAX(NVL(shipping_fee, 0))

の結果は変わらず、

1,000

となります。

「1,000円が2件あるから2,000円になる」ということはありません。

MAX は値を足し算する関数ではなく、グループ内で最も大きい値を返す関数だからです。


9. 一方、SUMはどうなる?

SUM はMAXとは違います。

4件目の注文には、

order_price = 4,000

が入っています。

そのため、

5,000
+ 3,000
+ 2,000
+ 4,000

となり、

14,000

になります。

結果は以下のようになります。

user_id max_shipping_fee total_order_price
100 1,000 14,000

ここが MAXSUM の大きな違いです。

MAX → 最大の値を返す
SUM → すべての値を合計する

10. NULLを0として扱うNVLとは?

ここまで何度も登場した、

NVL(shipping_fee, 0)

についても確認しておきましょう。

NVL は、

指定した値がNULLだった場合、別の値に置き換える

ための関数です。

基本的な書き方は、

NVL(, NULLだった場合の値)

です。

例えば、

NVL(shipping_fee, 0)

なら、

shipping_fee = 500
→ 500

shipping_fee = NULL
→ 0

となります。

今回の場合は、

「送料がNULLなら0円として扱いたい」

という意図で使用しています。


11. MAXとNULLの関係

ここは少し注意が必要です。

MAX は、基本的に NULL を無視して最大値を求めます。

例えば、

500
NULL
1,000

であれば、

MAX(shipping_fee)

の結果は、

1,000

です。

そのため、今回のように「NULLが混ざっているだけ」であれば、MAX 自体は最大値を取得できます。

では、なぜ、

MAX(NVL(shipping_fee, 0))

としているのでしょうか?

ポイントは、すべての値がNULLだった場合です。

例えば、

NULL
NULL
NULL

だった場合、

MAX(shipping_fee)

の結果は NULL になります。

一方、

MAX(NVL(shipping_fee, 0))

なら、

0
0
0

として扱うため、結果は、

0

になります。

つまり、

「NULLしかない場合でも0を返したい」

という要件がある場合に、NVL を組み合わせる意味があります。


12. MAXの基本構文を覚えよう

最後に、MAX の基本構文を整理しておきます。

SELECT MAX(カラム名)
FROM テーブル名;

例えば、

SELECT MAX(shipping_fee)
FROM orders;

です。

GROUP BY と組み合わせる場合は、

SELECT 
    user_id,
    MAX(shipping_fee)
FROM orders
GROUP BY user_id;

のようになります。

さらに、NULLを0として扱いたい場合は、

SELECT 
    user_id,
    MAX(NVL(shipping_fee, 0))
FROM orders
GROUP BY user_id;

と書けます。

NVL はOracle Databaseなどで使われる関数です。データベース製品によっては、COALESCEIFNULL などを使用します。


13. この記事のポイントを整理

ここまでの内容を整理すると、以下のようになります。

SQL 役割
GROUP BY 指定した項目ごとにデータをグループ化する
MAX グループ内の最大値を返す
SUM グループ内の値を合計する
NVL NULLを指定した値に置き換える

今回のSQLは、

SELECT 
     user_id
    ,MAX(NVL(shipping_fee, 0)) AS max_shipping_fee
    ,SUM(NVL(order_price, 0))   AS total_order_price
FROM 
    orders
GROUP BY 
    user_id;

なので、

ユーザーごとに注文をまとめて、その中から最高送料と購入金額の合計を取得している

と理解すればOKです。

特に覚えておきたいのは、この3つです。

GROUP BY → データをグループ化
MAX      → 最大値
SUM      → 合計値

そして、

NVL → NULLだった場合の値を指定する

と覚えておけば、今回のSQLの意味がかなり読みやすくなります。


さいごに

GROUP BYMAXSUM は、SQLでデータを集計するときに非常によく使われる基本的な機能です。

最初は、

MAX(NVL(...))

のように関数が入れ子になっていると難しく感じるかもしれません。

そんなときは、いきなりSQL全体を理解しようとせず、

① GROUP BYで誰ごとにまとめる?
        ↓
② MAXで何の最大値を取る?
        ↓
③ SUMで何を合計する?
        ↓
④ NULLはどう扱う?

という順番で考えると理解しやすくなります。

SQLの集計処理は、実務でも頻繁に登場します。

まずは、

「GROUP BYでグループを作る → 集計関数でグループ内のデータを集計する」

という基本の考え方をしっかり押さえておきましょう!

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?