SQLer 生島勘富 のブログ

RDB・SQLの話題を中心に情報発信をしています。

JOINとWHERE句に結合条件

 SQLは標準言語で、ISOやANSI、JISなどで規格が決められています。

 前回はFROM句とWHERE句について書きましたが、結合条件はFROM句に書いています。これはANSI 推奨の書き方です。ISO では、元々、WHERE句に書くように規定されていて、Oracleは ISO に準拠していました。

 ANSISQLServerDB2PostgreSQLなど)
     FROM TABLE_A AS a
       LEFT  JOIN TABLE_B AS b
         ON a.B_ID = b.ID

 ISO(Oracle
     FROM TABLE_A AS a
       , TABLE_B AS b
     WHERE
       a.B_ID = b.ID(+)

 ANSIは米国規格協会・米国標準協会 (American National Standards Institute) ですから、できる限り英語に近づけようとしたのかな、ISOは国際標準化機構で非英語圏にも配慮したのかな?と私は考えています。

処理から考える

 結合することは抽出にも繋がります。RDBMSオプティマイザはデータ量とデータの分散具合から、同じSQLでも処理をする順番を変えます。SQLは句毎に実行されるのですが、ANSIの書き方ではFROM句とWHERE句がごちゃ混ぜになって実行されることになります。


図1 結合処理から実行される場合のイメージ

図2 WHERE句から処理される場合のイメージ

 結合処理での絞り込みと、WHERE句での絞り込みと、より絞り込める方から実行されます。

 このイメージは重要で(ベン図である必要はないけれど)たくさんのテーブルを結合しても基本は同じなので、常に処理をイメージしながら書きましょう。

 処理をSQLに置き換えると ISO の書き方の方が一致しています。

意味から考える

 前回、抽出条件と結合条件の違いを意識しましょうと書きましたが、意味から考えると ANSI の方が正しいです。WHERE句に結合条件を書くと、抽出条件と結合条件の違いがはっきりしません。

 意味を取るか、処理を取るかは、読みやすさを取るか、書きやすさを取るかとも言えるでしょう。書きやすさとしては ISO、読みやすさとしては ANSI となります。

 Oracle 8までは、ANSI の書き方で書けなかったので、昔からのオラクラーは WHERE句に結合条件を書く人が多いのですけれど、Oracle 9から ANSI の書き方に対応しましたので、ベンダーの数からいっても ANSI の書き方が標準と考えてよいでしょう。

 というわけで、私もOracle 9以降は、ANSI の書き方をするようにしていますし、このブログも基本的に ANSI の書き方で進めます。

 処理から考える私としては、ごちゃ混ぜに実行される所に、若干違和感があって悩ましいのですけれど……。