SQLの集計関数とは?初心者でもわかる基本から応用まで
SQLでデータを扱う際、個々のレコードだけでなく、全体の傾向や特定のグループごとのまとまりを知りたい場面は非常に多いでしょう。
例えば、あるECサイトの売上データを分析する際に、「全商品の合計売上はいくらか?」「最も売れている商品はどれか?」「カテゴリごとの平均価格は?」といった疑問が浮かびます。
このような、複数の行をまとめて一つの値に変換する処理を「集計」と呼びます。
そして、SQLにはこの集計処理を簡単に行うための特別な関数群が用意されています。
それが「集計関数」です。
「集計関数って、なんか難しそう…」と感じるかもしれませんが、実は私たちが日常的に使っている計算や統計とほとんど同じ考え方です。
この記事では、SQLの集計関数について、その基本から実践的な使い方までを、具体的なSQLコードと実行結果を交えながら、分かりやすく解説していきます。
データ分析の第一歩として、集計関数をマスターしましょう。
データの「まとまり」を掴む!基本の集計関数5選
SQLでよく使われる集計関数は、主に以下の5つです。
COUNT(): 行数を数えるSUM(): 数値の合計を計算するAVG(): 数値の平均値を計算するMIN(): 数値や日付などの最小値を求めるMAX(): 数値や日付などの最大値を求める
これらの関数は、SELECT文の中で使用することで、テーブル全体のデータや、特定の条件に合致するデータの集計結果を得ることができます。
それでは、それぞれの関数を具体的な例で見ていきましょう。
1. COUNT(): データ件数を数えよう
COUNT()関数は、指定した条件に合致する行の数を数えるのに使われます。
最もシンプルな使い方は、COUNT(*)としてテーブル全体の行数を取得する方法です。
例えば、usersテーブルに登録されているユーザーの総数を調べたい場合、以下のように記述します。
SELECT COUNT(*) FROM users;
このクエリは、usersテーブルの全行数を返します。
もし、特定の条件を満たす行だけを数えたい場合は、WHERE句と組み合わせて使います。
例えば、usersテーブルから、年齢が30歳以上のユーザーの数を数えるには、次のようにします。
SELECT COUNT(*) FROM users WHERE age >= 30;
COUNT()関数は、特定の列を指定することもできます。
COUNT(column_name)のように列名を指定すると、その列にNULL以外の値が入っている行だけを数えます。
SELECT COUNT(email) FROM users;
この場合、email列がNULLでないユーザーの数を取得できます。
一般的に、テーブル全体の行数を数える場合はCOUNT(*)、特定の列の非NULL件数を数える場合はCOUNT(column_name)を使うことが多いです。
2. SUM(): 合計値を計算しよう
SUM()関数は、指定した列の数値の合計値を計算します。
例えば、ordersテーブルにある全注文の合計金額を計算したい場合、以下のように記述します。
SELECT SUM(amount) FROM orders;
このクエリは、ordersテーブルのamount列の全ての値を合計した結果を返します。
SUM()関数もWHERE句と組み合わせて、条件に合致するデータの合計値を計算できます。
例えば、ordersテーブルから、2023年に行われた注文の合計金額を計算するには、次のようにします。
SELECT SUM(amount) FROM orders WHERE order_date >= '2023-01-01' AND order_date < '2024-01-01';
SUM()関数は、数値型の列に対してのみ使用できます。
3. AVG(): 平均値を計算しよう
AVG()関数は、指定した列の数値の平均値を計算します。
SUM()関数と同様に、ordersテーブルの全注文の平均金額を計算したい場合は、以下のように記述します。
SELECT AVG(amount) FROM orders;
このクエリは、ordersテーブルのamount列の平均値を返します。
AVG()関数もWHERE句と組み合わせて、条件に合致するデータの平均値を計算できます。
例えば、usersテーブルから、30歳以上のユーザーの平均年齢を計算するには、次のようにします。
SELECT AVG(age) FROM users WHERE age >= 30;
AVG()関数も数値型の列に対してのみ使用可能です。
4. MIN(): 最小値を見つけよう
MIN()関数は、指定した列の最小値を求めます。
例えば、productsテーブルにある全商品のうち、最も安い価格を調べたい場合、以下のように記述します。
SELECT MIN(price) FROM products;
このクエリは、productsテーブルのprice列の最小値を返します。
MIN()関数は数値だけでなく、日付や文字列など、比較可能なデータ型に対しても使用できます。
例えば、usersテーブルで最も古い登録日を調べたい場合、次のようにします。
SELECT MIN(registration_date) FROM users;
5. MAX(): 最大値を見つけよう
MAX()関数は、指定した列の最大値を求めます。
productsテーブルの全商品のうち、最も高い価格を調べたい場合は、MIN()関数と同様に、MAX()関数を使います。
SELECT MAX(price) FROM products;
このクエリは、productsテーブルのprice列の最大値を返します。
MIN()関数と同様に、MAX()関数も数値、日付、文字列など、比較可能なデータ型に対して使用できます。
例えば、ordersテーブルで最も新しい注文日を調べたい場合、次のようにします。
SELECT MAX(order_date) FROM orders;
グループごとに集計!GROUP BY句との組み合わせ
ここまでは、テーブル全体のデータを対象とした集計関数について見てきました。
しかし、実際のデータ分析では、「カテゴリごとの平均価格」や「ユーザーごとの注文回数」のように、データを特定のグループに分けて集計したい場面がほとんどです。
そのような場合に活躍するのが、GROUP BY句です。
GROUP BY句を使うと、指定した列の値が同じ行をグループ化し、そのグループごとに集計関数を適用することができます。
例えば、productsテーブルで、商品カテゴリ (category) ごとの平均価格を計算したいとします。
この場合、AVG()関数とGROUP BY句を組み合わせます。
SELECT category, AVG(price) FROM products GROUP BY category;
このクエリは、まずproductsテーブルのデータをcategory列の値でグループ化します。
そして、各カテゴリグループごとにAVG(price)を計算し、その結果をcategoryとともに表示します。
実行結果は以下のようになるでしょう。
| category | avg(price) |
|---|---|
| Electronics | 150.50 |
| Books | 25.75 |
| Clothing | 55.20 |
このように、GROUP BY句を使うことで、より詳細で分析に役立つ集計結果を得ることができます。
複数の列でグループ化する
GROUP BY句では、複数の列を指定して、より細かくグループ化することも可能です。
例えば、ordersテーブルで、年 (YEAR(order_date)) と月 (MONTH(order_date)) ごとの注文数を集計したい場合、以下のように記述します。
SELECT YEAR(order_date) AS order_year, MONTH(order_date) AS order_month, COUNT(*) AS order_count
FROM orders
GROUP BY YEAR(order_date), MONTH(order_date)
ORDER BY order_year, order_month;
このクエリでは、order_dateから年と月を抽出し、それらを組み合わせてグループ化しています。
AS句を使って、集計結果の列に分かりやすい別名(エイリアス)を付けている点もポイントです。
集計結果をさらに絞り込む:HAVING句
GROUP BY句でグループ化した後、さらにそのグループ全体に対して条件を指定して絞り込みたい場合があります。
例えば、「注文数が100件以上のカテゴリだけを表示したい」といった場合です。
このような場合に使うのがHAVING句です。
HAVING句は、WHERE句とは異なり、集計関数を使った結果に対して条件を指定できます。
先ほどのカテゴリごとの平均価格の例にHAVING句を加えてみましょう。
例えば、平均価格が100円以上のカテゴリだけを表示するには、次のようにします。
SELECT category, AVG(price) FROM products
GROUP BY category
HAVING AVG(price) >= 100;
HAVING句は、GROUP BY句の後、ORDER BY句の前に記述します。
WHERE句は個々の行に条件を適用し、HAVING句はグループ化された結果に条件を適用する、という違いを理解しておきましょう。
集計関数を使う上での注意点
集計関数は非常に便利ですが、いくつか注意しておきたい点があります。
1. NULL値の扱い
集計関数は、基本的にNULL値を無視します。
COUNT(column_name):NULLは数えません。SUM(),AVG():NULLは計算対象から除外されます。MIN(),MAX():NULLは比較対象から除外されます。
例えば、AVG(price)を計算する際に、price列にNULLが含まれている行は、平均値の計算から除外されます。
もし、NULLを0として扱いたい場合は、COALESCE()関数などを使って明示的にNULLを置換してから集計を行う必要があります。
SELECT AVG(COALESCE(price, 0)) FROM products;
2. GROUP BY句とSELECTリストの関連
GROUP BY句を使用する場合、SELECTリストに含めることができるのは、基本的に以下のいずれかです。
GROUP BY句で指定した列- 集計関数を適用した結果
例えば、以下のクエリはエラーになります。
-- これはエラーになる例
SELECT category, price, AVG(price) FROM products GROUP BY category;
このクエリでは、categoryでグループ化していますが、price列はグループ化の対象でも集計関数でもありません。
そのため、どのpriceを表示すれば良いかSQLが判断できないためエラーとなります。
もし、グループごとの代表的なprice(例えば最小値や最大値)を表示したい場合は、MIN(price)やMAX(price)のように集計関数を使用する必要があります。
-- これは正しい例
SELECT category, MIN(price) AS min_price, MAX(price) AS max_price, AVG(price) FROM products
GROUP BY category;
3. 空のテーブルやグループ
集計関数は、対象となるデータがない場合、あるいはグループが存在しない場合に、特定の値を返します。
COUNT(*): 0 を返します。SUM():NULLを返します。AVG(),MIN(),MAX():NULLを返します。
これは、集計関数が「計算対象がない」という状態をNULLで表現するためです。
この挙動を理解しておかないと、予期せぬ結果に戸惑うことがあるかもしれません。
まとめ:集計関数でデータ分析の扉を開こう!
今回は、SQLの集計関数であるCOUNT(), SUM(), AVG(), MIN(), MAX()について、その基本的な使い方から、GROUP BY句と組み合わせたグループごとの集計、そしてHAVING句を使った絞り込みまでを解説しました。
集計関数は、データベースに蓄積された大量のデータから、全体像や傾向を把握するための強力なツールです。
これらの関数を使いこなすことで、データに基づいた意思決定や、より深い洞察を得ることが可能になります。
まずは、身近なテーブルで色々な集計関数を試してみてください。
「このテーブルの件数は?」「この商品の合計金額は?」といった素朴な疑問から始めて、徐々にGROUP BY句を使った複雑な集計へとステップアップしていくのがおすすめです。
SQL Questでは、今回学んだ集計関数を実践で試せる練習問題も豊富に用意しています。
ぜひ、次のステップへ進んで、集計関数のスキルをさらに磨きましょう!