本文へスキップ
BecomeCoder

SQL データ操作 (DML)コース · 第3章 テーブルをつなぐ · レッスン9

リレーションの種類 ― 1対多という関係

ブラウザで完結

導入

表と表のつながり方には「型」があります。もっとも基本で、いちばん多いのが 1対多(one-to-many, 1:N) です。「1人の会員が、たくさんの注文を持つ」――この関係を先に図でつかむと、JOIN が「なぜ・どうつなぐのか」がすっと理解できます。

説明

このショップ DB には、1対多の関係がいくつも埋め込まれています。

flowchart LR
    C["categories<br/>(カテゴリ)"] -->|"1つのカテゴリに<br/>多くの商品 1:N"| P["products<br/>(商品)"]
    U["users<br/>(会員)"] -->|"1人が<br/>多くの注文 1:N"| O["orders<br/>(注文)"]
    O -->|"1注文に<br/>多くの明細 1:N"| OI["order_items<br/>(注文明細)"]
    P -->|"1商品が<br/>多くの明細に登場 1:N"| OI

矢印は「1」の側から「多」の側へ引いています。読み方は「1つの users の行に、複数の orders の行がぶら下がる」。つなぎ目は必ず「主キーusers.id)↔ 外部キーorders.user_id」です。

本当に「1人が複数」なのか、実データで確かめましょう。

SELECT * FROM orders WHERE user_id = 1;

user_id = 1(佐藤さん)の注文が複数返ります。これが「1対多」の“多”の側です。逆に、ある注文(orders)に対応する会員(users)は必ず1人。この非対称が「1対多」です。

このほかに、1対1(1:1)や多対多(N:M)という関係もあります。多対多はこの章の後半(レッスン13)でじっくり扱います。

やってみよう

初期表示のクエリを実行し、佐藤さん(user_id = 1)に複数の注文がぶら下がっていることを確認しましょう。次に SELECT * FROM order_items WHERE order_id = 5; を実行し、「1つの注文(id=5)に複数の明細」がある――もう一段の1対多も見てみてください。

演習

products テーブルから、カテゴリ(category_id)が 1 の商品をすべて取り出してください(1つのカテゴリに複数の商品がぶら下がっている“多”の側を確認します)。

ヒント1を見る

SELECT * FROM products WHERE category_id = 1;

実際に動かしてみよう

下のエディタにクエリを書いて「実行」を押すと、ブラウザ内のSQLiteで結果が表示されます。本文の例をそのまま試したり、書き換えたりしてみましょう。

SQL — ブラウザ内で実行(SQLite)

ブラウザ内でSQLを動かす環境(SQLite)を読み込みます(初回のみ一瞬)。
スクロールして表示された時点でも自動で読み込まれます。