コース一覧
SQL実践:JOIN・サブクエリ・データ更新
結合の実践演習

SQL実践:JOIN・サブクエリ・データ更新

JOIN、集合演算、サブクエリ、CTE、DDL・DMLを学び、複数テーブルを組み合わせてデータベースを作成・更新する無料コースです。

1
テーブル結合
01. なぜ結合が必要か5分
02. INNER JOINの基本5分
03. LEFT/RIGHT OUTER JOIN5分
04. 複数テーブルの結合5分
05. 自己結合5分
06. 集合演算 UNION/INTERSECT/EXCEPT5分
07. 結合の実践演習5分
08. テーブル結合クイズ5分
2
サブクエリ活用
01. サブクエリとは5分
02. WHERE句のサブクエリ5分
03. FROM句のサブクエリ5分
04. SELECT句のサブクエリ5分
05. WITH句(CTE)の活用5分
06. サブクエリ実践クイズ5分
3
テーブル作成とデータ操作
01. CREATE DATABASE と CREATE TABLE5分
02. データ型の選び方5分
03. INSERT 文でデータを追加する5分
04. UPDATE 文でデータを更新する5分
05. DELETE 文でデータを削除する5分
06. 物理削除と論理削除5分
07. ALTER TABLE で構造を変更する5分
08. 制約 (NOT NULL / UNIQUE / DEFAULT)5分
09. TRUNCATE と DROP5分
10. DDL / DML 実践クイズ5分

結合の実践演習

「商品ごとの売上を出して」と言われて内部結合で書くと、1 個も売れていない商品が一覧から消えます。売れ筋の順位は見えますが、「どれが売れていないのか」という、たいてい本当に知りたいほうの情報が落ちています。

レポートの 1 行が何を表すかを、先に決める

今回作るのは「商品ごとに 1 行」のレポートです。商品が 5 件あるなら、注文が 0 件の商品も含めて 5 行出るのが正解になります。1 行が何を表すかを決めれば、主軸のテーブルが決まります。主軸を FROM の側に置き、そこから関連するテーブルを広げていきます。

ER 明細 4 件しかなくても、商品 5 件を 5 行のレポートで返す products5 件 id, name, price 未販売 2 商品ヘッドセット・ウェブカメラ orders3 件 idorder_date order_items4 件 order_idproduct_id quantity売れた商品の明細 product_id 5 件を減らさない集計 products を左へ主軸は 5 件のまま LEFT JOIN + GROUPCOALESCE(..., 0) 売上レポート 5 行未販売 2 商品も 0 個・0 円 商品 5 件・注文 3 件・明細 4 件。INNER JOIN ならヘッドセットとウェブカメラの 2 行が消える 空白ではなく 0 個・0 円まで作って初めて、売れていない商品も比較できるレポートになる

いきなり集計まで書かず、まず結合だけを書いて 1 度実行してみてください。

SQL クエリ

-- 段階 1 結合だけ書いて、右が NULL の行が残るかを確かめる
SELECT b.title, r.rating
FROM books b
LEFT JOIN reviews r ON b.id = r.book_id;

ここで相手のいない行が NULL を伴って並んでいれば、土台は正しく組めています。行数が足りなければ、結合の種類を間違えています。

空欄と 0 は、読み手にとって別のもの

集計の対象になる行が 1 つも無いグループでは、SUM も AVG も 0 ではなく NULL を返します。レポートに空欄が並ぶと、集計漏れなのか本当に 0 なのかが読み手に伝わりません。COALESCE(SUM(...), 0) の形で包み、0 だと言い切るところまでを SQL の仕事にします。

なお COUNT だけは対象が無くても 0 を返すので、包む必要がありません。集計関数によって振る舞いが違う点は覚えておいてください。

GROUP BY の書き漏らしは、環境が変わってから出る

SQL クエリ

-- title が GROUP BY に無い。標準の設定ではエラーになる
SELECT b.id, b.title, COUNT(r.id)
FROM books b
LEFT JOIN reviews r ON b.id = r.book_id
GROUP BY b.id;

SELECT に並べた列のうち、集計関数で包んでいないものは、すべて GROUP BY にも書きます。MySQL の緩い設定では書き漏らしても動いてしまうため、手元で通ったクエリが本番で落ちる、という形で表面化しがちです。最初から全部書く癖を付けておくのが安全です。

解説

並べ替えのキーは複数指定できます。1 つ目が同点になったときに順序が実行のたびに入れ替わると差分が取りづらいので、2 つ目に id のような一意な列を足しておくと結果が安定します。

テーブル構造

CREATE TABLE products (
  id INT PRIMARY KEY,
  name VARCHAR(50),
  price INT
);

CREATE TABLE orders (
  id INT PRIMARY KEY,
  order_date DATE
);

CREATE TABLE order_items (
  id INT PRIMARY KEY,
  order_id INT,
  product_id INT,
  quantity INT
);

INSERT INTO products VALUES
  (1, 'マウス',     2500),
  (2, 'キーボード', 8000),
  (3, 'モニター',   35000),
  (4, 'ヘッドセット', 6000),
  (5, 'ウェブカメラ', 4500);

INSERT INTO orders VALUES
  (1001, '2026-05-01'),
  (1002, '2026-05-03'),
  (1003, '2026-05-10');

INSERT INTO order_items VALUES
  (1, 1001, 1, 3),
  (2, 1001, 2, 1),
  (3, 1002, 3, 1),
  (4, 1003, 1, 2);

期待される出力

product_idproduct_nametotal_quantitytotal_revenue
3モニター135000
1マウス512500
2キーボード18000
4ヘッドセット00
5ウェブカメラ00

ヒント

LEFT JOIN を使えば未販売の商品も結果に残る

COALESCE(SUM(...), 0) で SUM が NULL のときに 0 を返す

GROUP BY には p.id と p.name を両方書く

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • テーブルDB の表 (Excel のシートみたいなもの)
  • 関連クラス間のつながりを表す直線
  • HTTPWeb の通信プロトコル、HTTPS は TLS で暗号化したもの
  • セット重複を持たない順序なし集合
  • None「値がない」ことを表す特別な値。
  • URLページの住所全体
  • JOIN複数テーブルをくっつけて 1 つの結果に並べる SQL
  • ループ繰り返し処理。矢印で戻すか専用記号で示す
query.sql
学習モード
エディタを読み込んでいます
コードの実行結果
データベースを初期化中...