こんにちは。@mosuke5です。
近頃、データベーススペシャリストの資格試験の勉強をしています。理由は、普段システムの開発・運用を行っているのですが、障害がデータベース起因のことが非常に多いです。また社内にデータベースに詳しい人も少ないので、どうしてもベンダー頼みになってしまうことも多いからです。
データベースの運用とは少しまた違うのですが、その第一歩としてデータベーススペシャリストを撮ろうと考えています。
追記
その後無事に資格の取得できました。
ちなみにIPA系はいつもこのシリーズで勉強しています。
テーブル結合の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がわかりやすいのではないかと考えています。 みなさんはどうかんがえていますか?