見出し画像

3分間データベース講座 第3回: 複数のデータを組み合わせる~結合(JOIN)と集約関数~



登場人物:

  • チャット先生(通称:先生): オブジェクト指向マスター。最近はデータベースの世界にも詳しい。

  • ボット助手(通称:ボット君): プログラミングを始めたばかりの若手。データベースはまだ未知の世界。


ボット君: 先生!前回、主キーと外部キーでテーブルを繋ぐ仕組みは理解できました。でも、実際にその繋がったテーブルからデータを取り出すにはどうすればいいんですか?「山田さんが注文した商品の名前」みたいな情報を知りたいんですけど、ユーザー情報と商品情報は別のテーブルにあるんですよね?

先生: 素晴らしい!まさにそこが今日の核心だ。データベースの真の力は、複数のテーブルに散らばったデータを組み合わせて、意味のある情報を引き出すことにある。そのための鍵が「結合(JOIN)」と「集約関数」だ。

1. 複数のテーブルを繋げる~結合(JOIN)

先生: 複数のテーブルを関連づけるには、JOINという機能を使う。これは、異なるテーブルにあるデータを、指定した共通の列を基準にして「横に並べる」操作だ。

先生: 例として、users(ユーザー)テーブル、products(商品)テーブル、orders(注文)テーブルを見てみよう。

users テーブル

+----+--------------+
| id | name         |
+----+--------------+
| 1  | 山田 太郎    |
| 2  | 佐藤 花子    |
| 3  | 鈴木 次郎    |
+----+--------------+

products テーブル

+----+--------------+--------+
| id | name         | price  |
+----+--------------+--------+
| 501| Tシャツ      | 3000   |
| 502| スニーカー   | 8000   |
| 503| キャップ     | 2000   |
+----+--------------+--------+

orders テーブル

+----+-----------+---------------+----------+
| id | user_id   | product_id    | quantity |
+----+-----------+---------------+----------+
| 101| 1         | 501           | 2        |
| 102| 2         | 502           | 1        |
| 103| 1         | 501           | 1        |
| 104| 3         | NULL          | 1        |
+----+-----------+---------------+----------+

先生: JOINにはいくつか種類があるんだが、最も基本的な「INNER JOIN」と、データが欠けていても結合できる「LEFT JOIN」を学んでいこう。

INNER JOIN:一致するデータだけを結合

先生: INNER JOINは、2つのテーブルの共通する列に一致する値があるデータだけを組み合わせて表示する。

-- ordersテーブルとproductsテーブルをINNER JOINで結合する
SELECT
    o.id AS order_id,
    o.user_id,
    p.name AS product_name, -- productsテーブルの商品名
    o.quantity
FROM
    orders AS o -- ordersテーブルに'o'という別名をつける
INNER JOIN
    products AS p ON o.product_id = p.id; -- productsテーブルを'p'という別名で結合

このクエリを実行すると、product_idがNULLの注文104は表示されない。

実行結果

+------------+---------+--------------+----------+
| order_id   | user_id | product_name | quantity |
+------------+---------+--------------+----------+
| 101        | 1       | Tシャツ       | 2        |
| 102        | 2       | スニーカー    | 1        |
| 103        | 1       | Tシャツ       | 1        |
+------------+---------+--------------+----------+

LEFT JOIN:左側のテーブルのデータをすべて残して結合

先生: LEFT JOINは、FROM句で先に指定したテーブル(左側のテーブル)のデータをすべて残し、右側のテーブルから一致するデータを結合する。一致するデータがなければNULLが表示される。

-- ordersテーブルのデータをすべて残してproductsテーブルと結合する
SELECT
    o.id AS order_id,
    o.user_id,
    p.name AS product_name,
    o.quantity
FROM
    orders AS o
LEFT JOIN
    products AS p ON o.product_id = p.id;

このクエリを実行すると、product_idがNULLの注文104も表示され、product_nameはNULLとなる。

実行結果

+------------+---------+--------------+----------+
| order_id   | user_id | product_name | quantity |
+------------+---------+--------------+----------+
| 101        | 1       | Tシャツ      | 2        |
| 102        | 2       | スニーカー    | 1        |
| 103        | 1       | Tシャツ      | 1        |
| 104        | 3       | NULL         | 1        |
+------------+---------+--------------+----------+

2. データを集計する~集約関数とGROUP BY

ボット君: 今度は、注文された商品ごとの合計数量を知りたいです。個別の注文ではなく、全体の集計です。

先生: そのような「データを集約(まとめる)」ときに使うのが「集約関数」だ。

代表的な集約関数には、次のようなものがある。

  • COUNT(): データの数を数える

  • SUM(): 合計値を計算する

  • AVG(): 平均値を計算する

  • MAX(): 最大値を求める

  • MIN(): 最小値を求める

先生: さらに、集計する単位を指定したい場合は、「GROUP BY」を使う。これは、指定した列の値が同じ行を一つのグループとして扱い、そのグループごとに集約関数を適用する機能だ。

例えば、「商品ごとの合計数量」を知りたい場合は、JOINしたテーブルをproduct_nameでGROUP BYしてからquantityをSUM()で合計すればいい。

-- 商品ごとの注文数量の合計を算出する
SELECT
    p.name AS product_name, -- 商品名
    SUM(o.quantity) AS total_quantity -- 注文数量の合計
FROM
    orders AS o
INNER JOIN
    products AS p ON o.product_id = p.id
GROUP BY
    p.name; -- 商品名ごとにグループ化する

このクエリの実行結果は、以下のようなイメージになる。

実行結果

+--------------+------------------+
| product_name | total_quantity   |
+--------------+------------------+
| Tシャツ      | 3                |
| スニーカー    | 1                |
+--------------+------------------+

WHEREとHAVING:集計前後の絞り込み

先生: GROUP BY句でデータを集計した後、さらに条件で絞り込みたい場合がある。その場合はWHERE句ではなく、「HAVING」句を使う。

  • WHERE: 集計前のデータを絞り込む

  • HAVING: 集計後のデータを絞り込む

-- 合計数量が2件以上の商品だけを表示する
SELECT
    p.name AS product_name,
    SUM(o.quantity) AS total_quantity
FROM
    orders AS o
INNER JOIN
    products AS p ON o.product_id = p.id
GROUP BY
    p.name
HAVING
    SUM(o.quantity) >= 2; -- 集計結果の合計数量が2以上のものに絞り込む

まとめと次回の予告

先生: 今日のまとめだ。

  • 結合(JOIN): 複数のテーブルを繋ぎ、データを組み合わせるための機能。**INNER JOINLEFT JOIN**などがある。

  • 集約関数: SUMやCOUNTなど、データの集計を行うための機能。

  • GROUP BY: 集計を行う際、どの列を基準にグループ化するかを指定する。

  • WHEREとHAVING: 集計前の絞り込みにはWHERE、集計後の絞り込みにはHAVINGを使う。

これらの機能を組み合わせることで、データベースからビジネスに役立つ情報を簡単に取り出せるようになる。

先生: 次回は、データベースのデータ品質を守るための「正規化」と「ER図」について学んでいこう。


次回:第4回: データベース設計の基礎~正規化とER図の考え方~

#データベース #SQL #結合 #JOIN #集約関数 #GROUPBY #HAVING #プログラミング学習


いいなと思ったら応援しよう!

ナオユキ|物語と知識のコンシェルジュ もしこの記事が少しでも役に立ったり、楽しんでいただけたりしたら、チップをいただけるととても嬉しいです! いただいたチップは、今後のより良いコンテンツ制作のための書籍代📚とnote購入🗒️、他の方へのチップ代💰に使わせていただきます。 いつも応援ありがとうございます!