メインコンテンツへスキップ

VillageSQL is a drop-in replacement for MySQL with extensions.

All examples on this page work on VillageSQL. Install Now →
INNER JOIN は一致が成立した行だけを残します。あるテーブルの行が別の テーブルの行を指していて、その両方が欲しいときに使う結合です。 始める前に mysql -u root -p sakila でクライアントを開いてください。

INNER JOIN の仕組み

COLUMN_LIST を欲しい列に、LEFT_TABLE を起点にするテーブルに、 RIGHT_TABLE を追加の列を取り出すテーブルに、各 COLUMN_NAME をそれぞれの 側で両者をつなぐ列に置き換えます。 ON 句はどの行同士が対応するかを指定します。MySQL は左テーブルの各行を 取り、その条件が成り立つ右テーブルの行を見つけ、一致ごとに 1 つの結合された 行を返します。何も見つからなかった行は、どちら側でも除外されます。 LEFT JOIN は、そうした行を代わりに残す句です。

例

  1. 2 つのテーブルを結合する

film.language_id は language.language_id を指しています。この組を 一致させれば、タイトルの横に言語名を表示できます。
1,000 行で、film 単体と同じ件数です。すべての映画がちょうど 1 つの言語に 一致しました。結合列が単一の行を指しているときはこうなります。

  1. 外部キーをたどって結合する

顧客の住所は別のテーブルに保存されています。
599 行、顧客 1 人につき 1 行です。

  1. 3 つのテーブルを結合する

テーブルを増やすごとに INNER JOIN 句を 1 つ追加します。Sakila は所在地を address、city、country に分けているので、都市名にたどり着くには 2 段階必要です。
依然として 599 行です。各結合が単一の行に一致したので、件数は動きませんでした。

  1. USING で短く書く

2 つの列が同じ名前のとき、USING が ON の代わりになり、名前を 1 回だけ 書きます。
例 1 と同じ 1,000 行です。USING は両側で名前が一致するときにしか使えない ので、常に使えるのは ON の形です。

複数行への一致は行を増やす

結合は一致ごとに 1 行を返すので、多数の行に一致する行は何度も返ってきます。 各映画には複数の俳優がいます。
1,000 本の映画から 5,462 行、各タイトルが俳優ごとに 1 回繰り返されています。 結合が予想より多くの行を返す通常の理由はこれであり、結合に対して計算した 合計が大きくなりすぎる理由でもあります。

人がつまずく 2 つのこと

一致しなかった行は空欄ではなく消える。 film ではなく language を 起点にしても、1,005 行ではなく 1,000 行が返ります。Sakila の他の 5 言語は どの映画にも一致せず、脱落します。内部結合は一致したものを報告し、欠けて いるものは決して報告しません。LEFT JOIN が、もう 一方の問いを立てる方法です。 ON の欠落はエラーにならない。 MySQL は ON のない INNER JOIN を 両テーブルのすべての組み合わせとして読むので、入力ミスはエラーではなく 1,000 × 6 行を返します。CROSS JOIN では、意図的な 場合と偶発的な場合の両方を扱います。

まとめ

  • 一致するテーブルの行を組み合わせるには、INNER JOIN を ON と共に使います。
  • テーブルを増やすごとに INNER JOIN 句を 1 つ追加します。
  • 一致しない行は消えます。内部結合は一致したものだけを報告するからです。
  • 1 行が多数の行に一致すると、行数が増えます。
  • USING は、列が両側で同じ名前のときにだけ使います。

関連項目