0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【SQL】外部結合のつもりが、内部結合に! ?

Posted at

はじめに

業務でSQLを書いていると
外部結合をしたい場面に出くわすことがよくあります。

正規化されたテーブルは、
だいたいトランザクションにコードだけが入っていて、
その名称を取得しようとする場合、マスタと外部結合しますよね。

例えばコンビニのレシート

コンビニレシートの明細がトランザクションとしたとき、商品コードが明細に登録され、
商品マスタが別に存在するという状況をイメージして下さい。

そして、商品にグループがあって、
あるグループの商品だけ名称を取得したいときは、、条件を付けますね。
いい例が思いつかず、変な例ですいません。m(_ _)m

本題

ここで本題です。
条件の位置によって、外部結合のつもりが内部結合になるという事象にぶつかります。

いや、知ってますよ~。
という方はここで読むのをやめてもらってOKです。

え!? ホントに?
という方だけ続きを読んでください。

それでは、具体的な例を見ていきましょう。

前提

先にコンビニレシートを例にしたのを引継ぎ、そのイメージで進めます。
コンビニレシート:3商品買った。そのうち、1つは「飲み物」とします。
※あえて、飲み物だけ商品名を表示しないとします。
また、変な例ですw

SELECT文

ざっくりですが、下記のようなイメージのSQLで取得できます。
明細は、3行取得されます。

select
明細.商品コード
商品マスタ.商品名
商品マスタ.商品価格
from
明細
left outer join 商品マスタ
on (
明細.商品コード = 商品マスタ.商品コード
and 商品マスタ.グループ <> ’飲み物’ 
)
where
明細.お会計シーケンス = ’いまのお会計のユニークNo
order by
明細.バーコードを読み取った順

SELECT文(条件の位置を変えてみる)

上記のSQLの「飲み物」以外という条件をwhereの方に持って行きます。
明細は2行取得され、なんと「飲み物」の行が消えます。

select
明細.商品コード
商品マスタ.商品名
商品マスタ.商品価格
from
明細
left outer join 商品マスタ
on (
明細.商品コード = 商品マスタ.商品コード
- and 商品マスタ.グループ <> ’飲み物’  --★条件を移動(削除する)
)
where
明細.お会計シーケンス = ’いまのお会計のユニークNo
+ and 商品マスタ.グループ <> ’飲み物’  --★ここに移動(追加する)
order by
明細.バーコードを読み取った順

なぜ「飲み物」の行が消えたのか?

これは、どの段階で条件が適用されるのかが理解できれば、
簡単にわかるはずです。

  • from句
    from句に条件があるときを見てみます。
    「明細」に「left outer join 商品マスタ」を外部結合する。
    その時の条件として、on句に「商品マスタ.グループ <> ’飲み物’」の条件があるとき、
    商品マスタを「飲み物以外」に絞った結果と「明細」を外部結合します。
    (商品マスタから「飲み物」がなくなった状態で、外部結合しているイメージ)

  • Where句
    Where句に「商品マスタ.グループ <> ’飲み物’」の条件があるときを見てみます。
    明細と商品マスタを外部結合した「結果」のデータに対して、条件を付けている事になります。
    (明細と商品マスタを外部結合した時点では、「飲み物」の行がある。)

よって、外部結合したのに、
内部結合したかのような結果が取れてしまいます。

勘のいい方は、もうわかった!と思っていることでしょう。
厳密には記述通りに動作していていますから、
「本題」で書いた「内部結合になる」の記述は間違いですね。ごめんなさい。

まとめ

今回は、いつ適用されるのか?が焦点でした。
group byや、order byなどの句がいつ適用されるのかを意識すると、思わぬ不具合を回避できます。
十分に分かっている方も一度見直してみたら、新たな発見があるかも知れません。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?