28 Feb 2014, 23:28

INNER JOIN とWHERE結合の違いについて理解する

こんにちは。@mosuke5です。
近頃、データベーススペシャリストの資格試験の勉強をしています。理由は、普段システムの開発・運用を行っているのですが、障害がデータベース起因のことが非常に多いです。また社内にデータベースに詳しい人も少ないので、どうしてもベンダー頼みになってしまうことも多いからです。
データベースの運用とは少しまた違うのですが、その第一歩としてデータベーススペシャリストを撮ろうと考えています。

追記

その後無事に資格の取得できました。

テーブル結合の2つの記述方法

RDBMSを勉強すれば、すぐにテーブル結合について学びます。2つのテーブルの情報を何かのキーを使って結合するものです。 その結合の方法について、データベーススペシャリストの勉強をしていると見慣れない記述方法がされており戸惑ったことがこのブログを書いたきっかけです。
普段、アプリケーションの開発時にテーブルを内部結合するときには、INNER JOINを使って書いていましたが、 「FROM句のあとに複数のテーブルを書いてWHERE句で絞り込む」という記述方法もあるようです。 具体的に何が違うのか?同じなのか?書き方はどうか?見ていきます。

前提

以下のようなuserテーブルとorderテーブルがあると想定します。 そして、テーブル結合によりorderの内容とuserを紐づけたいとします。

userテーブル

user_id name age
1 Taro Shinagawa 24
2 Hiroshi Meguro 35
3 Goro Gotanda 33

orderテーブル

order_id user_id product
1 1 りんご
2 2 なし
3 1 おれんじ
4 3 ぶどう

INNER JOIN型

まずは、INNER JOIN型です。自分は一番見慣れた形式です。

SELECT * FROM order INNER JOIN user ON order.user_id=user.user_id

WHERE型

SELECT * FROM user,order WHERE order.user_id=user.user_id

結果は一緒です。ですが記法的にすこし考え方が異なりそうです。その考え方がわかればたいしたことはないです。 INNER JOIN型では、orderとuserのテーブルのuser_idが同じものをくっつけます。と解釈できますね。

一方、WHERE型は、まずSELECT * FROM user,orderこれの結果を考えるとわかりやすいです。 テーブル名を2つ並べるとクロスでかけ合わせます。 この中から、userのuser_idとorderのorder_idが同じものを選ぶ、と考えればWHERE型も納得ができますね。

user_id name age order_id user_id product
1 Taro Shinagawa 24 1 1 りんご
2 Hiroshi Meguro 35 1 1 りんご
3 Goro Gotanda 33 1 1 りんご
1 Taro Shinagawa 24 2 2 なし
2 Hiroshi Meguro 35 2 2 なし
3 Goro Gotanda 33 2 2 なし
1 Taro Shinagawa 24 3 1 おれんじ
2 Hiroshi Meguro 35 3 1 おれんじ
3 Goro Gotanda 33 3 1 おれんじ
1 Taro Shinagawa 24 4 3 ぶどう
2 Hiroshi Meguro 35 4 3 ぶどう
3 Goro Gotanda 33 4 3 ぶどう

どちらがよいか

どちらがよいか?という見出しにしましたが、どちらがいいということは基本的にないと思います。 しかし、頭のなかの理解のしやすさや、その他SQLの運用のことをいろいろ考えてみると、やはりFROM句の後にテーブルを複数書いてWHEREで結合させるのはナンセンスだと自分は考えています。
例えば、内部結合に加え、外部結合もある場合を考えてみます。

WHERE型

SELECT * 
FROM table1, table2 #←結合させたいもの
LEFT OUTER JOIN (
 ・
 ・
<副問い合わせとか長いSQLが入ると想定>
 ・
 ・
) AS sub
ON table1.id=sub.id AND table2.id=sub.id
WHERE table1.id=table2.id #←結合条件
 

table1とtable2を内部結合させたいのに、肝心の何と何を結合させるかの部分の”WHERE table1.id=table2.id”が離れてしまい、SQL文全体として何をしたいかわかりずらいきがします。

一方、INNER JOINなら

SELECT * 
FROM table1
INNER JOIN table2 ON table1.id=table2.id #←結合させたいものと結合条件が一緒
LEFT OUTER JOIN (
 ・
 ・
<副問い合わせとか長いSQLが入ると想定>
 ・
 ・
) AS sub
ON table1.id=sub.id
 

上記のように、結合させたいテーブルと結合させる条件がくっつくため、全体としてなにをしたいかわかりやすいと考えます。 慣れの問題や書き方によって改善できるのかもしれませんが、圧倒的にINNER JOINがわかりやすいのではないかと考えています。 みなさんはどうかんがえていますか?

関連する記事はこちら
  • Datadog APMとトレーシングの仕組みについて (2019/11/21)
  • [基礎] ElasticSerachなどの外部コンポーネントがあるときのテスト (2019/05/26)
  • SlideShare APIをGoogleAppsScriptから利用する (2018/12/20)
  • Docker Compose上でのRailsアプリケーションの開発フロー (2018/05/02)
  • PHPでhttpヘッダー、x-forwarded-forを受け取る (2016/07/26)
  • comments powered by Disqus
    このエントリーをはてなブックマークに追加