SQL のコーディングスタイル

SQL のコーディングスタイルってあんまり語られなくて、よくある自動整形ツールが倣う有名なスタイルはあったりするんだけど、有名といった割に知名度が低かったり、そんで結局オレオレな書き方になってることが多い。

自分もご多分に漏れずオレオレな書き方なんだけど、「インデントで表現する」がモットーになってるのかな、と思って、紹介してみる。

以下、適当に思いつきで作ったテーブルを適当に結合したりしていくつか SELECT 文を書いてみる。ココで話したいのはコーディングスタイルであってテーブルの構成とか IN 句の是非とかではない。あと自分がよく使うのが Oracle DB なので、構文は Oracle 寄り。

SELECT
    A.COLUMN1,
    A.COLUMN2,
    B.DATA1,
    B.DATA2
FROM
    TABLE_A A
    INNER JOIN TABLE_B B
        ON  A.ID = B.ID
        AND A.NO = B.NO
WHERE
    A.COLUMN1 = 'hoge'
AND A.COLUMN2 IN ('foo', 'bar')
ORDER BY
    COLUMN1,
    COLUMN2
;
SELECT
    C.TITLE,
    C.PRICE,
    D.NUM
FROM
    TABLE_C C
    LEFT JOIN
        (
            SELECT
                ID,
                TYPE,
                NUM
            FROM
                TABLE_E E
            WHERE
                TYPE IN (
                    SELECT
                        TYPE,
                        GROUP
                    FROM
                        TABLE_F
                    WHERE
                        GROUP = 'F'
                )
        ) D
        ON  C.ID = D.ID
WHERE
    (
       (TITLE LIKE '%AAA%' AND PRICE >= 800)
     OR
       (TITLE LIKE '%BBB%' AND PRICE <= 500)
    )
AND D.NUM > 5
;

基本はスペース4つのインデントのかたまりで表現

SELECT
    *
FROM
    テーブル
WHERE
    条件
ORDER BY
    カラム

が原型。

UNION の時は、

SELECT
    (中略)
UNION
SELECT
    (中略)

と書きがち。

カンマは行末に打つ

行頭に置く方がメリット多いとは思うんだけど、見た目が気持ち悪いという気分的な理由だけで従わない。というのは、英語の文章を考えた時に、手前の文書とカンマの間はスペースが入らなくて、カンマの後ろにスペースが入るべきだ。「hogehoge, fugafuga.」と。

カンマが行頭に来るスタイルはこれが「hogehoge ,fugafuga .」とか「hogehoge , fugafuga . 」となっているような違和感があり、英文を読む感覚で SQL を読めなくなるので、書かない。

WHERE 句は条件のインデント位置を揃える

ANDOR の位置にクセがある。

WHERE
    (条件)
AND (条件)
OR  (条件)

みたいにする。

同じ理由で JOIN の結合条件もそうしてる。JOIN (テーブル名) の行はテーブル名が出てくるので、最初のテーブル名 (以下のサンプルなら TABLE_A) の行と同じインデント位置にする。んで結合条件は結合のための条件でいわば補足的な内容と見なし、JOIN よりインデントしている。

FROM
    TABLE_A A
    INNER JOIN TABLE_B B
        ON  A.ID = B.ID
        AND A.NO = B.NO
    INNER JOIN TABLE_C C
        ON  A.ID = C.ID

サブクエリ系は GNU スタイル風

インデント量が増えるが、「この中身だけ読めばサブクエリが完結してますよ」感を出したくて、カッコでインデント、サブクエリはさらにインデント、としている。

FROM
    TABLE_C C
    LEFT JOIN
        (             ← この辺!
            SELECT    ← さらにインデントしてる
                *
            FROM
                TABLE_E E
        ) D    ← こんな感じ

でもたまに K&R スタイルのカッコもやる

小さめなヤツはインデント量をごまかしたりしてる。

WHERE
    TYPE IN (    ← ココが違う
        SELECT
            *
        FROM
            TABLE_F
    )    ← この閉じカッコは開きカッコがある行のインデントと同じ数になる

あんまり統一感ない。

OR 条件と AND 条件が絡む場合はカッコを多めに使う

ぼくは頭が悪いので、AND・AND・OR・AND、みたいに並ぶと、イチイチ「OR だから、手前と一緒に判断されて…」みたいな優先順位を整理しておかなくちゃいけなくて、それが面倒臭いので、「色々条件は絡んでくるけど、これらでひとまとまりのグループです」っていう明示をするために、なくても変わらないカッコでも書くことが多い。

んであとはインデントでひとまとまり感を表現。以下は OR 条件のそれぞれが複雑な場合を想定した感じだけど、通常のスペース4つのインデントよりは縮めて書いて、「グルーピングのためのカッコと、混同しないようにするための字下げ位置の変更であって、結局はこの全体が見えてないとダメなんですよ~」感を出してる。

WHERE
    (
       (TITLE LIKE '%AAA%' AND PRICE >= 800)
     OR
       (TITLE LIKE '%BBB%' AND PRICE <= 500)
    )

この辺インデントのルールとかがない。

WHERE
    NUM = 800
AND ( (TITLE LIKE '%AAA%' AND PRICE >= 800)
     OR
      (TITLE LIKE '%BBB%' AND PRICE <= 500) )

こういう横着パターンも多い。

実はあんまりルールとかなかったかも

WHERE 句に複数条件が並んだ時の書き方は基本やる。

サブクエリのインデントは内容の複雑さと長さに応じて GNU スタイル風か K&R スタイル風かを変えてる。

そんなところでしょうか。

皆さんは自分の流儀とかありますか?