【SQL入門】3つのテーブルを1つにまとめて集計する方法|JOINとGROUP BY+WITHで読みやすくする

雑記

背景

データベースを扱うとき、「複数のテーブルを結合して最終的に件数を出したい」 という場面はよくあります。

例えば次のような構造を考えてみましょう。

  • Aテーブル … 拠点や住所などの基本情報
  • Bテーブル … Aテーブルと紐づく組織コードを持つ
  • Cテーブル … Bテーブルの組織コードを使って所属ユーザーを管理している

最終的には「拠点+組織ごとのユーザー数」を1本のSQLで取得したいわけです。


よくある分割クエリ

まずは単純に分けて考えるとこうなります。

AとBを結合

SELECT DISTINCT
    B.組織コード,
    A.拠点コード,
    A.住所
FROM Aテーブル A
LEFT JOIN Bテーブル B
    ON B.拠点コード = A.拠点コード;

Cで件数を集計

SELECT
    組織コード,
    COUNT(ユーザーID) AS 件数
FROM Cテーブル
GROUP BY 組織コード;

3テーブルをまとめたクエリ

実際には JOINを重ねてGROUP BYするだけ で、1つにまとめられます。

NULLを0として残す場合

SELECT
    B.組織コード,
    A.拠点コード,
    A.住所,
    COALESCE(COUNT(C.ユーザーID), 0) AS 件数
FROM Aテーブル A
LEFT JOIN Bテーブル B
    ON B.拠点コード = A.拠点コード
LEFT JOIN Cテーブル C
    ON C.組織コード = B.組織コード
GROUP BY
    B.組織コード,
    A.拠点コード,
    A.住所;

件数が存在する組織だけ出したい場合

SELECT
    B.組織コード,
    A.拠点コード,
    A.住所,
    COUNT(C.ユーザーID) AS 件数
FROM Aテーブル A
INNER JOIN Bテーブル B
    ON B.拠点コード = A.拠点コード
INNER JOIN Cテーブル C
    ON C.組織コード = B.組織コード
GROUP BY
    B.組織コード,
    A.拠点コード,
    A.住所;

ポイント

  • 3テーブルを1本のクエリでまとめる
    A → B → C とJOINを重ねればOK
  • COUNTとGROUP BYで集計
    件数を集めたいカラムを基準にまとめる
  • NULLをどう扱うか
    • LEFT JOIN + COALESCE() → 件数が無くても0で表示
    • INNER JOIN → 件数がある組織だけ抽出

WITH(共通テーブル式)で可読性を上げる

そんな時に便利なのが WITH句(Common Table Expression, CTE) です。
サブクエリに名前をつけて、処理を段階的に整理できます。

WITHを使った例

USE SampleDB;

WITH q1 AS (
  SELECT DISTINCT
      a.Unit_Code,        -- 組織コード
      p.Location_Code,    -- 拠点コード
      p.Location_Name     -- 拠点名
  FROM A_Location_Master p
  LEFT JOIN B_Unit_Location a
    ON a.Location_Code = p.Location_Code
),
q2 AS (
  SELECT
      o.Unit_Code,
      COUNT(o.User_Id) AS EmployeeCount
  FROM C_Employee_Unit o
  GROUP BY o.Unit_Code
)
SELECT
    q1.Unit_Code,
    q1.Location_Name,
    q2.EmployeeCount
FROM q1
INNER JOIN q2
  ON q2.Unit_Code = q1.Unit_Code;


ポイント解説

  • q1 … 拠点と組織コードをまとめた部分(A+B)
  • q2 … 組織ごとの件数をまとめた部分(Cの集計)
  • 最後に両者を結合して「拠点+組織ごとの件数」を取得

👉 このように 処理を2段階に分けて名前をつける ことで、SQLの流れがはっきりします。


まとめ

  • JOINとGROUP BYを組み合わせると、3テーブルをまとめて集計できる
  • COALESCEを使えばNULLを0として扱える
  • WITHを使うとクエリの見通しが良くなり、ナレッジとして共有する時にも分かりやすい

SQLは「動けばOK」ではなく、「読みやすさ・保守しやすさ」も大事です。
特に社内ナレッジとして残す場合、WITHで分割して説明しやすくするのがおすすめです。

コメント

タイトルとURLをコピーしました