SQL鬼練11/ 3hour
Sep / 38hour
Total / 139.5hour
SQLのJOINについて
複数のテーブルを結合して情報を引っ張ってくる「JOIN句」。
ここではその種類と使い方、また実際にどのようにデータベースから情報を取ってきているのかをみていきます。
JOIN句の種類と書き方
JOIN句は大きく分けて三つあります。
- JOIN (INNER JOIN) – 内部結合のこと。複数のテーブルを比較して、条件に一致したデータだけを返す。
- RIGHT (OUTER) JOIN – 外部結合のこと。複数のテーブルを比較して条件に一致したデータを返すが、後述するJOINというキーワードを中心とした右側のテーブルのデータも、条件に一致していなくても結果を返すもの。
- LEFT (OUTER) JOIN – RIGHT JOINの左側バージョン。
書き方
SELECT カラム名1, カラム名2, … FROM テーブル1 JOIN テーブル2 ON 結合の条件 (+絞り込みの条件)
・・・て言われてもちっともイメージ湧かないですよね。僕は上記のような式をみたときに「???」でした。
次に、実際にどう使っていくのか?をみていきましょう。
JOIN句を使用する具体例
まずは参照するデータがないと話しにならん、ということで下記の二つのデータを基にみていきます。
テーブル:users
テーブル:products
イメージとしては、userが顧客情報でproductsがその顧客が購入した商品のリスト、といった感じです。
INNER JOIN
やりたいこと
「usersテーブルから全てのカラムを取得して、それにusersのidとproductsのuser_idを対応させた上で、productsというテーブルをくっつけてデータを取りたいな」
SQL文
SELECT * FROM users INNER JOIN products ON users.id = user_id
ON句のあとの「users.id」となっている部分は、「.」を用いることで「users”の”id」を表しています。
結果を見ると、あら不思議。二つのテーブル同士がくっついてデータが返ってきました。
ただ一つ注目して欲しいのは、usersテーブルにいた「id=5の橋下徹」さんがデータに反映されていません。
これがINNER JOINの特徴で、あくまでINNER JOIN君は「条件に一致した結果のみしか返さない」からです。
今回の例でいうと、usersのidとproductsのuser_idとを結合の条件として両者をドッキングしましたが、よく見るとproductsの方に橋本徹さんのuser_idはありません。
なので、INNER JOINでは橋本徹さんは省かれて結果が返ってきた、というわけです。かわいそうですね。
RIGHT JOIN
次はRIGHT JOIN について。
比較しやすいようにproductsに下記のレコードを追加します。
*本当は存在しないユーザーIDが商品のテーブルにある、というのはありえないですがわかりやすいように作成しました。
この状態で下記のようなSQL文で、RIGHT JOINを実行すると・・・
SELECT * FROM users RIGHT JOIN products ON users.id = user_id
何ですかね、この「NULL」って奴は・・・。
RIGHT JOINというのは、
「RIGHT JOINからみて右側のテーブルを基準として、条件に当てはまるデータを取ってきてください。あと、右側のテーブルが基準となるから、そのテーブルのデータは条件とマッチしなくてもデータは全て返してね」
という命令です。
なので、今回の場合はusersとproductsのテーブルで、products側を基準としてusers.idとuser_idを結合条件としてデータを取ってきた結果、「ipod classicはusersのテーブルの中に紐づいたidはないけど、RIGHT JOINって言われてるから、一応データ返すで。でもマッチしないから、usersの方はNULLやけどな」
となった感じです。
それに加えて、右側基準でデータを取得してきているので購入履歴がない橋下徹さんはまたしても今回は省かれています。
かわいそうですね。同姓同名の方がいたらごめんなさい・・・。
LEFT JOIN
では、LEFT JOINを使って下記のようなSQL文を作成するとどうなるのか。
SELECT * FROM users LEFT JOIN products ON users.id = user_id
今度は先ほどのRIGHT JOINと逆で、LEFT JOINを基準として左側のusersテーブルを基準にデータを取得する、という命令になります。
なので、先ほど省かれていた橋下徹さんもデータとして返ってきてます。ただ、products側には橋下徹さんの購入履歴はない(idはない)ので値が「NULL」として返ってきてる、ということです。
WHEREを使ってさらに条件を絞ってみよう
例えば、次のようなデータを取ってきたい場合・・・
「usersにある鈴木花子さんの購入履歴だけをデータとして引っ張ってきたいな」
これを実行するには、どのようなSQL文を書けばいいのでしょうか。
それには、WHEREという便利な奴がいます。
WHEREって何?という方はこちらの記事をご参照ください。
本日のプログラミング学習 PHP 鬼練5~10 / 3hour Aug / 39.5hour Total / 64.5hour 通勤で読んでいる書籍 30minitues […]
こいつを使って下記のようなSQL文を書いてみると・・・
SELECT * FROM users INNER JOIN products ON users.id = user_id WHERE users.id = 2
こんな感じで、鈴木花子さんの購入履歴だけのデータを引っ張ってくることができました。
二台もMacBook買うなんて、お金持ちですね。
JOINは本当に便利
最初に、呪文のように見えたSQL文も慣れればこんなに使い勝手のいい奴はいません。
大事なのは「どのテーブルとどのテーブルを比較するか、内部結合?外部結合?、どのカラムで結合するの?」ということを抑えることです。
そうすれば、自分の意図したデータが引っ張ってこれるとおもいます。
ちなみに三つ以上のデータも結合できます。
それはまた別の機会に。
参考
JOINは複数のテーブルを連結させるために用意されたキーワードです。単純にテーブルを連結させる以外にも、LEF[…]
MySQL Casual Advent Calendar 2016 - Qiita 12日目の記事です。 まさかの3回目。もうムリ。。。 JOIN ON句で結合条件ではなく絞込条件を書くことができることを、知らなかったのです。 具体的な名称[…]
学習は全てウェブカツ!!というプログラミングスクールで学んでいます。
大手スクール生徒や現役エンジニアが多数学び直している「実務レベル」に特化した「稼ぐ」ためのプログラミングスクール[…]