Agent Grow Tech Notes
🧑‍💻

【SQL】結合の構文で省略可能なものは、省略するべきか?(INNER/OUTER)

に公開

結合の構文

開発業務でSQLを扱う際に、結合を全く使わないプロジェクトはあるのでしょうか?
少なくとも、私は必ず使う現場にしか入ったことがありません。

そういうわけで、今回は結合の構文について『機能的に変わらないが、どうなのか?』が気になる部分にフォーカスした内容を紹介します。

『変わらない』とは?

外部結合

たとえば、次の構文は同じ動作ですが、違いについて気にしたことはありますか?

-- その1
SELECT [抽出項目] FROM [テーブル1] LEFT OUTER JOIN [テーブル2] USING([結合キー]);

-- その2
SELECT [抽出項目] FROM [テーブル1] LEFT JOIN [テーブル2] USING([結合キー]);

上記は『左外部結合』の例ですが『OUTER』の有無が違います。
ですが、動作は全く同じです。

具体例をPostgreSQLで書きますので、よろしければ試してみてください。
※簡単に試す方法はこちらの記事を参考にして下さい。

-- テーブル定義~データ作成まで
CREATE TABLE table1 (
   id   INTEGER PRIMARY KEY
 , name VARCHAR
)
;
CREATE TABLE table2 (
   id   INTEGER PRIMARY KEY
 , age  INTEGER
)
;
INSERT INTO table1 VALUES
  (1,'たろう')
 ,(2,'はなこ')
 ,(3,'じろう')
 ,(4,'ももこ')
 ;
 INSERT INTO table2 VALUES
  (1,15)
 ,(3,13)
 ,(5,18)
 ;

下記の2つを実行し、結果を比較してみましょう。

-- OUTERあり
SELECT * FROM table1
LEFT OUTER JOIN table2 USING(id)
ORDER BY id ;

-- OUTERなし
SELECT * FROM table1
LEFT JOIN table2 USING(id)
ORDER BY id ;

結果はどちらも同じです。

内部結合

一方、内部結合はどうでしょうか?

-- その1
SELECT [抽出項目] FROM [テーブル1] INNER JOIN [テーブル2] USING([結合キー]);

-- その2
SELECT [抽出項目] FROM [テーブル1] JOIN [テーブル2] USING([結合キー]);

今度は『INNER』の有無が違います。
ですが、動作は全く同じです。

下記の2つを実行し、結果を比較してみましょう。

-- INNERあり
SELECT * FROM table1
INNER JOIN table2 USING(id)
ORDER BY id ;

-- INNERなし
SELECT * FROM table1
JOIN table2 USING(id)
ORDER BY id ;

こちらも結果は『あり/なし』ともに同じです。

補足

よく見ると、外部結合も内部結合も2つのSQLでは実行時間が違うのですが(先に実行の方が時間がかかっている
これは順番を入れ替えると、構文に関わらず先に実行した方がかかっていました。
連続で実行しているためとは思いますが、今回は実行時間についての違いは度外視します。
(環境によりけりで、キャッシュや実行計画などの影響もあり得るため)

省略する?しない?

ルールに『従う』

皆さんひとりひとりが、担当されている現場/プロジェクト/チームで決められたルールに従うのが前提になります。

ですので、コーディング規約などに「省略してはいけない」と書いてあれば、省略しません
逆に「省略する」と書いてあれば、省略します

ルールを『決める』

では、もしご自身がルールを決める立場になったら、どうしますか?
省略の有無で、どちらが必ず正解ということはないと考えられますが、現場の状況に応じてメリット/デメリットを比較し、適切な方を採用することになるでしょう。

ただし『決めない』のは良くないと思われます。
担当者によって省略したり、しなかったりバラバラになり、様々なトラブルの温床となり得ます。

『業務システム』開発視点での『個人的な』見解

↑見出しの通り『B to B』が多くなりがちな業務システムで考えると・・・

省略しない!

が、良いと『私は』考えます。
一番の理由は、安全性です。

ここでは例として、外部結合で抽出した結果を顧客(取引先、得意先)に納品するシステムと仮定します。

【1.OUTERを省略する場合】

SELECT * FROM table1
LEFT JOIN table2 USING(id)
ORDER BY id ;

なにかの原因で『LEFT』が削られてしまった場合(置換のミスなど)

SELECT * FROM table1
JOIN table2 USING(id)
ORDER BY id ;

この場合 『外部結合』が『内部結合』に変わってしまいます。
エラーが発生せずに、意図しない結果が顧客に納品される恐れがあります!

【2.OUTERを省略しない場合】

SELECT * FROM table1
LEFT OUTER JOIN table2 USING(id)
ORDER BY id ;

なにかの原因で『LEFT』が削られてしまった場合(置換のミスなど)

SELECT * FROM table1
OUTER table2 USING(id)
ORDER BY id ;

この場合、構文エラーが発生します。
エラーが解消されるまでは顧客に納品はできませんが『意図しない結果が顧客に納品される』ことはありません。

業務を考えた場合、間違った結果を正として扱うことの方が、リスクは大きいです。
なぜなら、納品した顧客の更にその先にも関係する顧客が居て影響はどんどん広がってしまいます

仮にエラーのため一時的に納品ができないときは、事情を説明して待っていただいたり代替策による対応も出来るはずです。

以上がユーザ業務の視点で考える、私の個人的な見解です。

さいごに

今回は、SQLの構文について色々と語ってみました。
しかし、やはり最終的にはユーザ業務の視点で締めるような形になりました。

あくまでも『個人的』な見解なので、この記事を読んで「省略する方が、私の現場には合っている」ということであれば、それで良いと思います。

重要なのは『システムを安定稼働させて、ユーザ業務に支障が出ないこと』だと考えています。

ここまでお付き合い頂き、ありがとうございましたm(_ _)m

Agent Grow Tech Notes
Agent Grow Tech Notes

Discussion