SQL テーブルを結合するJOIN文を初心者向けに解説しました
データベースを使ったアプリの開発を始めたあなた! ページに必要な情報をデータベースから取ってくるのに、何度も何度もSELECT文を書くのは効率が悪いと思いませんか?
例えば、ログイン履歴とユーザの名前を画面に表示したい場合に「ユーザ名を検索」→「紐づくログイン履歴を検索」→「データを加工」といった処理を作ってはいないでしょうか?
処理がふえるとバグも発生しやすくなりますし、表示内容が変わったとき変更が大変になりますね。
JOINをつかえば、そんな無駄な処理やリスクを減らすことができるのです。
目次
JOIN (テーブル結合とは?)
読んで字のごとく、テーブル結合とは複数のテーブルを結び合わせることです。
データベースから情報を取ってくるとき、必要な情報が複数のテーブルに格納されている場合って結構あると思います。
そんなときに関連付け(結合条件)を元に、複数のテーブルにある情報をひとつにまとめる方法がJOINです。
結合には種類が5つあります。ここでは良く使う内部結合 (INNER JOIN)、左外部結合 (LEFT OUTER JOIN)、右外部結合 (RIGHT OUTER JOIN)について説明します。
●内部結合 (INNER JOIN)
:条件にあった行だけを表示します。
●外部結合
┗左外部結合 (LEFT OUTER JOIN)
:条件に合わなくてもJOIN 句の左にあるテーブルの行を全て表示します。
┗右外部結合 (RIGHT OUTER JOIN)
:条件に合わなくてもJOIN 句の右にあるテーブルの行を全て表示します。
┗完全外部結合 (FULL OUTER JOIN)
:全ての行を表示します。 ※あまり使用されません。
●クロス結合(CROSS JOIN)
:可能な組み合わせ全てを表示します。 ※あまり使用されません。
JOINの使いどころ
僕もそうでしたが、初心者の頃だと、テーブル毎にデータを取ってこようとしますが、それだとデータベースに何度もアクセスすることになり、処理が重くなってしまいます。。。
そのため、JOINを使って複数のテーブルをまとめることで1回のアクセスで複数のデータを取ることができるんです! さて、では実際の活用例を見ていきましょう!
冒頭に出ていたのログイン履歴とユーザ情報を例にして実際にSQLを実行して動きを見てみましょう。
-- ログイン履歴テーブル作成 CREATE TABLE history ( customer_id smallint, login_dt timestamp); -- ログイン履歴情報 INSERT history SET customer_id='1', login_dt = "2018-11-17 16:44:28"; INSERT history SET customer_id='1', login_dt = "2018-11-16 16:44:28"; INSERT history SET customer_id='2', login_dt = "2018-11-15 16:44:28"; INSERT history SET customer_id='9', login_dt = "2018-11-14 16:44:28"; INSERT history SET customer_id='3', login_dt = "2018-11-13 16:44:28"; INSERT history SET customer_id='1', login_dt = "2018-11-12 16:44:28"; INSERT history SET customer_id='9', login_dt = "2018-11-11 16:44:28"; INSERT history SET customer_id='3', login_dt = "2018-11-10 16:44:28"; INSERT history SET customer_id='2', login_dt = "2018-11-9 16:44:28"; INSERT history SET customer_id='2', login_dt = "2018-11-8 16:44:28"; INSERT history SET customer_id='1', login_dt = "2018-11-7 16:44:28"; INSERT history SET customer_id='9', login_dt = "2018-11-6 16:44:28"; INSERT history SET customer_id='9', login_dt = "2018-11-5 16:44:28"; -- ユーザ情報テーブル作成 CREATE TABLE customer ( customer_id smallint, name varchar(40), sex tinyint); -- ユーザ情報 INSERT customer SET customer_id='1', name = "山田たろう", sex=1 ; INSERT customer SET customer_id='2', name = "鈴木しずか", sex=2 ; INSERT customer SET customer_id='3', name = "林はなこ", sex=2 ; INSERT customer SET customer_id='4', name = "木村いちろう", sex=1 ; INSERT customer SET customer_id='5', name = "森だいすけ", sex=1 ;
内部結合 INNER JOINの場合
さっそくINNER JOINでcustomer_idで紐づくログイン情報とユーザ情報を結合してみましょう。
下記のSQLをそのままコピーして実行してみてください。
-- INNER JOIN SELECT history.customer_id, history.login_dt, customer.name, customer.sex FROM history INNER JOIN customer ON history.customer_id = customer.customer_id ORDER BY history.login_dt DESC; -- 並び順はlogin_dtの降順
実行結果は下記になります。条件に合致した行だけ表示されているので、条件に合致しない「customer_id=9」の履歴は表示されていません。
- select * from history INNER JOIN customer on history.customer_id = customer.customer_id ;
- select * from history JOIN customer on history.customer_id = customer.customer_id ;
- select * from history , customer where history.customer_id = customer.customer_id ;
左外部結合 LEFT OUTER JOINの場合
今度は左外部結合でログイン情報とユーザ情報を結合します。
※SQLはINNER JOINのときのSQLを「INNER JOIN」→「LEFT OUTER JOIN」に変更します。
LEFT OUTER JOINは条件に合わなくてもJOIN 句の左にあるテーブルの行を全て表示します。この場合は左に書いている履歴テーブル(history)の行が全て表示されていますね!
-- LEFT OUTER JOIN サンプル SELECT history.customer_id, history.login_dt, customer.name, customer.sex FROM history LEFT OUTER JOIN customer ON history.customer_id = customer.customer_id ORDER BY history.login_dt DESC; -- 並び順はlogin_dtの降順
条件に合致していなくても履歴テーブルの行は全て表示されるので、「customer_id=9」の履歴も表示されています。
右外部結合 RIGHT OUTER JOINの場合
つぎは右外部結合でログイン情報とユーザ情報を結合してみます。
※SQLはLEFT OUTER JOINのときのSQLをRIGHTに変更しただけです。
RIGHT OUTER JOINの場合は条件に合わなくてもJOIN 句の右にあるテーブルの行を全て表示します。この場合は右に書いているユーザ情報(customer)の行が全て表示されていますね!
-- RIGHT OUTER JOIN SELECT history.customer_id, history.login_dt, customer.name, customer.sex FROM history RIGHT OUTER JOIN customer ON history.customer_id = customer.customer_id ORDER BY history.login_dt DESC; -- 並び順はlogin_dtの降順
軸になるテーブルがユーザ情報になるのでログイン履歴のない「木村いちろう」「森だいすけ」も表示されています。
検索条件(WHERE)を指定した場合
さいごに検索条件(WHERE)を指定した結合の動きを見てみましょう。
先ほど実行した右外部結合に検索条件「WHERE customer.sex = 1 」を追加します。
-- 検索条件(WHERE)を指定した結合 SELECT history.customer_id, history.login_dt, customer.name, customer.sex FROM history RIGHT OUTER JOIN customer ON history.customer_id = customer.customer_id WHERE customer.sex = 1 -- 検索条件を追加 ORDER BY history.login_dt DESC; -- 並び順はlogin_dtの降順
指定した検索条件のとおり、男性のみ抽出されました。
JOINのメリット(通常のSELECTと比較)
複数のテーブルから情報がほしい場合、JOINをしないと下記のようにたくさんの無駄に複雑な処理を書かなくてはいけません。
■通常のSELECTの場合の処理
1.ログイン履歴を検索
2.ユーザ情報を検索
3.ロジックでログイン履歴をクルクルまわしながらcustomer_idが一致するか判定
4.一致する場合、名前をログイン履歴の情報に追加
5.画面に表示
1~4をすべてまとめた情報にして取得できるのが結合(JOIN)です。
■JOINさせた場合の処理
1.ログイン履歴、ユーザ情報を結合して検索
2.画面に表示
とてもシンプルな処理になりました!
JOINの書き方
まとめ
- JOINを使うことで、SELECT文の発行回数を減らせる
- JOIN文にも種類があります、欲しいデータによって使い分けましょう
今回は、SQLのテーブルを結合するJOIN文を初心者向けに解説しましたがいかがでしょうか?
データベースを使った開発ではSQLは必ず使うスキルになります。
今回解説したJOINはとても便利ですので、ぜひ使ってみてくださいね!
さらに詳しく知りたい方や、もっとデータベース・SQLを学びたい人はこちらの書籍がおすすめです!
僕も辞書替わりに今でも持ってますよー
勉強コンテンツやLINE@であなたをサポート
ココカラエンジニアでは初心者向けの勉強コンテンツを用意していますので、ぜひご活用ください。
また、LINE@では就職・転職に関しての質問も受け付けています。
解決できないエラーなどプログラミングについての相談にも乗りますので、ぜひお気軽にご登録ください。
SQLは全てコピーしてそのまま使用できますので、ぜひ実際にSQLを実行してJOINの動きを確認してみてください!