こんにちは。ワタナベです。当ブログをご覧いただきありがとうございます。
開発者の皆さん、SQL文を書くとき、どうしたら綺麗に書けるのか悩む場面って多くないですか?プロジェクトによって、人によって書き方が違ったり・・・。人によって違うのはまだ良いとしても、読みにくい場合はたちが悪いですよね。
今回は具体的なSQL文を例示することで以下の問題を解決し、世の中のSQL文の質とプロジェクトの品質・保守性の向上に貢献したいと思います。
- どうやったら綺麗に書けるの?
- どうやったら見やすいの?
- 綺麗に書くと、どんな良いことがあるの?
以上の悩みを解決してきます。
ぜひ最後までお読みいただければと思います。
目次
この記事の信頼性
私は業務系アプリの開発者として15年以上この業界で仕事をしています。プログラマー、テスター、プロジェクトリーダー、保守担当など様々な立場でSQL文を書いたり・見たりしていますので、好みがわかれる部分があったとしてもこの記事で紹介する書き方を守っておけば間違いはないと言えるでしょう。
最初に完成形のSQL文を紹介
まずは結論として完成形のSQLをお見せします。この状態にそろえることがゴールとなります。
SELECT T.COL1
,T.COL2
,T.COL3
,CASE WHEN T.COL4 = 'YYY' THEN 'CONVERT_YYY'
WHEN T.COL4 = 'ZZZ' THEN 'CONVERT_ZZZ'
ELSE 'CONVERT_ELSE'
END CNV_COL4
FROM TRAN1 T
INNER JOIN MASTER1 M
ON T.COL1 = M.CODE1
WHERE T.COL1 = 'KEY'
AND M.CODE2 = 'XXXX'
ORDER BY T.COL1
,T.COL2
,T.COL3
では、具体的に「この状態」とはどういうことなのか1つずつ掘り下げてみていきましょう。
SELECT、FROMなどのキーワードは右寄せ、かつ大文字にする
これらのキーワードを右寄せかつ大文字にすることでSQLの全体像が視覚的につかみやすくなります。
カラム名はデータベース設計に基づいて小文字でも良いですが、私の場合はすべて大文字(DB設計時点で大文字)にします。
良い例です
SELECT COL1
,COL2
FROM TRAN1
WHERE COL1 = 'XXX'
AND COL2 = 'YYY'
悪い例です
select col1,col2 from tran1 where col1 = 'XXX' and col2 = 'YYY'
これだとSQL文が短いうちは良いですが、複数のJOINやCASE文が出てきたら解読が困難になってしまいますね。
1項目1行
SELECT句やORDER BY句で複数項目記述することが多々ありますが、同一行に複数項目書くのではなく、1項目につき1行使いましょう。
良い例です
SELECT COL1
,COL2
,COL3
,COL4
,COL5
,COL6
FROM TRAN1
悪い例です
SELECT COL1,COL2,COL3,
COL4,COL5,COL6 FROM TRAN1
これだと項目の増減が発生したときに不具合を出しやすいのと、どの項目が抽出されているのか時間がかかりますね。
複数項目列挙時のカンマは先頭に記載
SELECT句やORDER BY句で複数項目記述するときのカンマは先頭に記載しましょう。
そうしておくと、項目の増減が発生した際に容易に修正できます。特に最終項目に追加や削除が発生したときに力を発揮します。
末尾にカンマを記述していた場合、最終項目を単純に行削除すると、修正後の最終項目の末尾にカンマが残っていることになり構文エラーで落ちてしまいます。
良い例です
SELECT COL1
,COL2
,COL3
FROM TRAN1
悪い例
SELECT COL1,
COL2,
COL3, --←単純に項目削除でこの行を削除してしまうと構文エラーになる。(COL2の後ろにカンマがあるから)
FROM TRAN1
たったこれだけでバグの出方がだいぶ違いますよ。おすすめです。
JOINはインデント、ONはさらにインデント
JOIN句が出てくるとどうしても記述が長くなってしまうものです。インデントを活用して複数のJOINを記述したときでも見やすくしましょう。
良い例
・・・
FROM TRAN1 T
INNER JOIN MASTER1 M
ON T.COL1 = M.COL1
AND T.COL2 = M.COL2
INNER JOIN MASTER2 M2
ON T.COL1 = M2.COL1
AND T.COL2 = M2.COL2
悪い例
・・・
FROM TRAN1 T INNER JOIN MASTER1 M ON T.COL1 = M.COL1 AND T.COL2 = M.COL2
INNER JOIN MASTER2 M2 ON T.COL1 = M2.COL1 AND T.COL2 = M2.COL2
この悪い例はたまにホントに見ますね。きっと書いてる本人もどうすれば良いかわからなく「もういいや!」と諦めているのがよくわかります。もしくは、作った後の事など考えていないような印象も受けます。
あとでそのソースの面倒見る立場の人間から勘弁してほしいですね。作った後の未来の自分や保守をする人のことを思いやりましょう。
インデントはTAB文字ではなくスペース(空白)で
意見が分かれるポイントかと思いますが、コード中ではTAB文字は使わずにスペースで表現しましょう。
エディタや使う人の設定によって、揃っていたと思われるSQL文が崩れて見えてしまうことがあります。ですので、TAB文字は使わないようにします。
そういう意味では、フォントもプロポーショナルフォントも使わないようにしましょう。ご存じかと思いますが、文字によって幅が異なるのでSQL文の縦のラインがそろわなくなります。
まとめ
以上のポイントをまとめると、冒頭のSQL文になります。
SELECT T.COL1
,T.COL2
,T.COL3
,CASE WHEN T.COL4 = 'YYY' THEN 'CONVERT_YYY'
WHEN T.COL4 = 'ZZZ' THEN 'CONVERT_ZZZ'
ELSE 'CONVERT_ELSE'
END CNV_COL4
FROM TRAN1 T
INNER JOIN MASTER1 M
ON T.COL1 = M.CODE1
WHERE T.COL1 = 'KEY'
AND M.CODE2 = 'XXXX'
ORDER BY T.COL1
,T.COL2
,T.COL3
そしてポイントの復習です。
- SELECT、FROMなどのキーワードは右寄せ、かつ大文字にする
- 1項目1行
- 複数項目列挙時のカンマは先頭に記載
- JOINはインデント、ONはさらにインデントインデントはTAB文字ではなくスペース(空白)で
最後に
最重要なポイントは以上となります。ここまでお読みいただきありがとうございました。
SQL文の作法に困っている方からすれば少なからずお役に立てたはずです。まずはこの型を守れば大きな事故にはなりません。
いずれにせよ、コードというものは書いた本人でさえも1週間、1か月と時間が経ってしまえば細かいことは忘れているものです。ましてや他人がそのコードを見るのであれば見やすさというものはとても重要です。
読みにくいコードは、面倒を見る人を困らせ、最終的にはお客様を困らせてしまうことになってしまいます。
言い換えれば将来の誰か(面倒を見る人)を思いやることでお客様も不具合から守ることになります。
SQLだけでなくこの考え方は常に持っていたいと思います。
最後までお読みいただきありがとうございました。