【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
Discussion