読みにくいSQLは保守性を下げる
SQLが数行程度であればよいですが、行数が増えてくると、適切に改行やインデンストを設定してSQLを見やすく整形しないと、読みにくいSQLになり、メンテナンス性が下がります。
この記事では、SQLに改行やインデンストを挿入して、SQLを見やすく整形する方法を手法を解説します。
読みにくいSQLの例
まずは「読みにくいSQL」の例を見てみましょう。
select users.id, users.name, depts.dept_name,
sum(scores.score) from users inner join depts on depts.dept_no = users.dept_no
left outer join scores on scores.id = users.id
where users.age >= 30 and scores.record between '2020/01/01' and '2020/12/31'
group by users.id, users.name, depts.dept_name,order by sum(scores.score), users.age
いかかですか?
すこし極端な例かもしれませんが、上のSQLを見て、すぐにどんなSQLかを判断できる人は少ないでしょう。
それでは、上のSQLを読みやすくするために、改行やインデントを挿入して見やすくしていきましょう。
SQLの整形ルール
まず、SQLをどのように整形していくかルールを決めましょう。
このルール決めは重要で、システム開発プロジェクトの現場でも、「SQL規約」という文書を作成し、SQLを作成する前にSQLの整形ルールを決め、人によって改行・インデントの書き方がバラバラになるのを防ぐことが多いようです。
- SELECT / FROM / WHERE / GROUP BY / ORDER BYの後には改行を入れる
- カラム・テーブル・条件の指定は1行に1つ
- AND / ORの条件は行の先頭に記述する
- ブロックごとにインデント挿入し、インデントを揃える
- JOIN句のON句の前に改行しインデントを設定
- 予約語/関数は大文字で記述し、予約後以外は小文字で記述する
読みやすくSQLを整形する
実際に、前述したSQL整形ルールを使用して、前述の「読みにくいSQL」を整形していきます。
SELECT / FROM / WHERE / GROUP BY / ORDER BYの後には改行を入れる
SQLの予約後の後に改行を入れます。SELECT / FROM句などの予約語は、SQLのブロックを認識する上で重要なキーワードになるため、1行に単独で書くのが望ましいと言われています。
select
users.id, users.name, depts.dept_name,
sum(scores.score)
from
users, inner join depts on depts.dept_no = users.dept_no
left outer join scores on scores.id = users.id
where
users.age >= 30 and scores.record between '2020/01/01' and '2020/12/31'
group by
users.id, users.name, depts.dept_name,
order by
sum(scores.score), users.age
これで、対象SQLが見やすくなったのではないでしょうか?
では、続きのルールを適用してSQLを見やすくしていきましょう。
カラム・テーブル・条件の指定は1行に1つ
1行に複数のカラムや条件を書いてしまうと、可読性が悪くなるため、カラムやテーブル、および条件の指定は1行につき1つまでとします。
select
users.id
, users.name
, depts.dept_name
, sum(scores.score)
from
users
inner join depts on depts.dept_no = users.dept_no
left outer join scores on scores.id = users.id
where
users.age >= 30 and
scores.record between '2020/01/01' and '2020/12/31'
group by
users.id, users.name,
depts.dept_name,
order by
sum(scores.score),
users.age
AND / ORの条件は行の先頭に記述する
AND ORなどの条件は、行の先頭にもってくることで、WHERE句に指定されている条件が分かりやすくなります。
where
users.age >= 30
and scores.record between '2020/01/01' and '2020/12/31'
ブロックごとにインデント挿入し、インデントを揃える
SELECT FROMなどのブロック毎にインデントを挿入すると、構文構造が分かりやすくなります。今回はインデントを半角スペース2つにします。
select
users.id
, users.name
, depts.dept_name
, sum(scores.score)
from
users
inner join depts on depts.dept_no = users.dept_no
left outer join scores on scores.id = users.id
where
users.age >= 30
and scores.record between '2020/01/01' and '2020/12/31'
group by
users.id, users.name,
depts.dept_name,
order by
sum(scores.score),
users.age
ここまでくると、あの読みにくかったSQLが、かなり見やすくなってきたのではないでしょうか?
JOIN句のON句の前に改行しインデントを設定
テーブル結合部分のJOINやON句にも適切に改行やインデントを設定し、SQLを見やすくします。
from
users
inner join depts
on depts.dept_no = users.dept_no
left outer join scores
on scores.id = users.id
予約語/関数は大文字で記述し、予約後以外は小文字で記述する
最後に、大文字と小文字を役割毎に使い分けることで、よりSQLを見やすくしていきます。
一般的に、予約後や関数名は大文字、カラム・テーブル名は小文字で記述していきます。
SELECT
users.id
, users.name
, depts.dept_name
, sum(scores.score)
FROM
users
INNER JOIN depts
ON depts.dept_no = users.dept_no
LEFT OUTER JOIN scores
ON scores.id = users.id
WHERE
users.age >= 30
AND scores.record BETWEEN '2020/01/01' AND '2020/12/31'
GROUP BY
users.id, users.name,
depts.dept_name,
ORDER BY
sum(scores.score),
users.age
いかかでしょう?
最初の読みにくかったSQLが、かなり見やすくなったのではないでしょうか?
ツールによるフォーマットも使おう
SQLを1つずつ手作業でフォーマットするのは大変です。
SQLが1つ2つしかないシステムであれば、手作業でも問題ないかもしれませんが、業務系のシステムなどでは、SQLの数が数千ファイルになることもあり、それらを今回のように手作業でフォーマットをするのは現実的に不可能です。
そこで、SQLを実行する「Object Bloser」や「などのツールには、SQLの整形機能がついているものがあります。
SQLをツールのエディタに貼り付けて、ボタンをクリックするだけでSQL文を見やすく整形するツールが多く、インデントとして挿入するスペースの数や、どの位置に改行を挿入するかを細かく指定できるツールもあります。
基本的には、SQLを作成するタイミングで、読みやすいSQLに作成しておくことがベストですが、ツールを使って整形することもできます。
【関連記事】
▶SQL DeveloperでSQLを見やすく整形する方法を解説!