はじめに
SQL をレビューする際に、業務に関係なく、機械的にチェックしているポイントです。
select 句
null のケアはしているか
null制約がない項目に対する計算と文字列結合は、null の考慮が必要になります。
記憶を頼りに実装する開発者が多いため、必ず、DDLを確認しながらをチェックしています。
not null 制約の項目であっても外部結合している場合は、null になることがあるので周囲が必要です。
0で割っていないか
DBの制約により絶対に0にならないことが保証されていない場合以外は、業務上、1以上になる項目であっても 0 を考慮するようにしてもらっています。
日付の加減を日付型に対して関数を使って行っているか
日付の加算を ORDER_DATE + 1 のよう書いてあるのを見たことあります。作りによっては、月末月初以外はちゃんとした結果になることもあるので、注意が必要になります。
(「2019/7/1 + 1 -> 2019/7/2」で問題なく動作し、「2019/7/31 + 1 -> 2019/7/32」で初めて発覚する。)
結合条件の項目は、軸にしているテーブルの値を取得しているか
inner join の場合は、結合している側と結合されている側のどちらの項目を取得しても結果は同じですが、left outer join の場合は、結合する側の結合条件の項目を取得すると、null になってしまうことがあります。
select
T2.ID
, T2.NAME
from
T1
left outer join T2
on T1.ID = T2.ID
select
T1.ID
, T2.NAME
from
T1
left outer join T2
on T1.ID = T2.ID
from 句
from 句でテーブルを結合していないか
カンマでテーブルを並べ、where句でで結合することもできますが、どのように結合したいのかが分かりにくくなるためよろしくありません。
まれに、結合条件なしでテーブルを結合することがありますが、その場合は、cross join を使います。
select
T1.ID
, T2.NAME
from
T1
, T2
where
T1.ID = T2.ID
select
T1.ID
, T2.NAME
from
T1
inner join T2
on T1.ID = T2.ID
外部結合は left outer join で統一されているか
分かりにくくなるため、right outer join は使わず、 left outer join に統一した方がよいです。
結合条件に、Primary Key の結合忘れがないか
結合忘れがあると1レコードが複数レコードに膨らみます。
記憶を頼りに実装する開発者が多いため、必ず、DDLを確認しながら結合条件忘れをチェックしています。
where 句
not in を使っていないか
パフォーマンスの理由から、not exists を使いましょう。
ちなみに「in ではなく、exists を使え」というのは、パフォーマンス的には間違っている場合があります。
or は括弧でまとめているか?
or 条件は、問題なくても保守性の観点から括弧で条件をまとめるようにした方がよいです。
おわりに
基本的なことですが、意外とミスしている人が多いのでまとめました。
その他あれば、ぜひともコメントお願いします。