【これだけ】SQLの結合【現役エンジニアが解説】

PROGRAM

今回はSQLの結合について、事例を交えて簡単に解説していきます。
この記事では、基本よりも実践で使えるものを優先して解説していきます。

内部結合

データベースを使っていると、2つのテーブルを組み合わせて情報を取得したいときが必ず出てくると思います。
そんなときは、結合という概念を使うと、2つのテーブルに共通となるキーで結合して情報を取得することができます。

ここではブログのデータベースを想定してみましょう。

まず、ブログの記事を投稿する各ユーザの情報が入っているテーブルがあると思います。
ここでは以下のようにusersテーブルを想定します。

user_id name
1 山田太郎
2 田中花子
3 小林一郎

次に、ブログに投稿された各記事の情報が入っているテーブルがあると思います。
ここでは以下のようにpostsテーブルを想定します。

post_id title body user_id
1 初投稿 テスト投稿です。 1
2 こんにちは テスト投稿2です。 1
3 はじめまして テスト投稿3です。 2

今ここでブログに投稿された記事のタイトルとその投稿ユーザの一覧を表示したいとしましょう。

するとSQL文は、

SELECT title, user_id FROM posts;

上記のようになりますが、これでは投稿ユーザのIDしか取得できず、名前を取得することができません。
なぜなら、postsテーブルにはuser_idしか入っておらず、ユーザ名の情報はusersテーブルの方にあるからです。

このようなときに結合の概念が活躍します。

SELECT p.title, u.name FROM posts AS p INNER JOIN users AS u ON p.user_id = u.user_id;

上記のように、JOIN句を使うことで、2つのテーブルを結合し、それぞれで必要な情報をピックアップすることができます。
今回の場合は、usersテーブルのキーカラムであるuser_idが、postsテーブルにもあるため、それをキーにして結合しているわけですね。

外部結合

先程紹介した例は結合の中でも、内部結合というものになります。
結合の基本は内部結合であり、内部結合は両方に必要な情報が入っているという前提です。

一方、先程のブログで、ログインしていない一見さんでも投稿ができる仕組みであったとしたらどうでしょう。
すると、postsテーブルのuser_idに値が入っていない可能性があるので、usersテーブルと結合できず、取得すらされないレコードが出てきてしまいます。

そこで、そのような場合には外部結合という概念を使います。

SELECT p.title, u.name FROM posts AS p LEFT JOIN users AS u ON p.user_id = u.user_id;

上記のSQL文で、postsテーブルをベースにして、usersテーブルでヒットしない場合にはユーザ名はNULL値を返してもらうことができます。

SELECT文以外でも使える

結合はSELECT文で使われる頻度がかなり多いですが、SELECT文以外でも使えます。

例えば、先程のブログの例で言えば、山田太郎というユーザ名の記事のみを削除したい場合を想定してみましょう。

削除対象はあくまでpostsテーブルのレコードですが、山田太郎というユーザ名の情報はusersテーブルに入っているので、SQL文は少し工夫する必要がありますね。

そのような場合、DELETE文に結合を使うことになります。

DELETE FROM posts AS p INNER JOIN users AS u ON p.user_id = u.user_id WHERE u.name = '山田太郎';

postsテーブルをusersテーブルと結合して、usersテーブルのユーザ名を条件にすることで、ユーザ名が山田太郎の記事だけを削除することができます。