エンジニアのひよこ_level10

【毎日更新!】新卒2年目エンジニアブログです! プログラムだけじゃなく、マネジメントとかも書いていきたい!

【SQL】インデント等使いこなして、SQLを見やすくしてみよう!【514日目】

SQLって見にくいこと多いですよね

よく、自分や他の人のSQL文を見直すのですが、まーーーーあ見にくい。

ってことで、見やすいSQL文ってどんなのだろう?

友人2人と一緒に私のSQL文をリファクタリングしてみました!

元コード

 SELECT
 DISTINCT
  rankings.*,
  CASE
   WHEN user_types.id = 3 THEN 5
   WHEN user_types.id = 2
    OR user_types.id = 5
    OR user_types.id = 6 THEN 6
   WHEN user_types.id = 1
    OR user_types.id = 4
    OR user_types.id = 7 THEN 7
   WHEN user_types.id = 8 THEN 8
   ELSE 0
  END AS ranking_type_id
 FROM `db`.rankings
 RIGHT JOIN `db`.user_types ON rankings.user_id = user_types.id
 WHERE rankings_term_id = 8
 ORDER BY rankings.group_id, ranking_type_id, rankings.rank;

うおっ、詰まってる。
ただ、最低限の改行を使ってるだけまだマシ・・・?

~~句と式に改行を入れる

友人Z君の改変

SELECT
    DISTINCT rankings.*,
    CASE
        WHEN 
            user_types.id = 3
        THEN 5
        WHEN
            user_types.id = 2 OR user_types.id = 5 OR user_types.id = 6
        THEN 6
        WHEN
            user_types.id = 1 OR user_types.id = 4 OR user_types.id = 7
        THEN 7
        WHEN 
            user_types.id = 8
        THEN 8
        ELSE 0
    END AS ranking_type_id
FROM
    `db`.rankings
RIGHT JOIN
    `db`.user_types
ON
    rankings.user_id = user_types.id
WHERE
    rankings_term_id = 8
ORDER BY 
    rankings.group_id,
    ranking_type_id,
    rankings.rank
;

おおおお!!!

長くなりましたがいい感じですね。

極力SQLの~~句と式を同列に書かないようにしているようです。

WHERE rankings_term_id = 8

WHERE
    rankings_term_id = 8

見やすさ段違いですね!

さらにZ君ひと手間。

変数を扱う

MySQLの特性ですが

SET @aId = 5, @bId = 6, @cId = 7, @dId = 8, @eId = 0;

SELECT
    DISTINCT rankings.*,
    CASE
        WHEN 
            user_types.id = 3
        THEN @aId
        WHEN
            user_types.id = 2 OR user_types.id = 5 OR user_types.id = 6
        THEN @bId
        WHEN
            user_types.id = 1 OR user_types.id = 4 OR user_types.id = 7
        THEN @cId
        WHEN 
            user_types.id = 8
        THEN @dId
        ELSE @eId
    END AS ranking_type_id

いい感じ。ここには用途は書いてないですが、実務では、変数に意味のある言葉をつければ、
より可読性が増しますね!

すると、友人O君がぼそっと・・・

ORじゃなくてIN句使う

SET @aId = 5, @bId = 6, @cId = 7, @dId = 8, @eId = 0;

SELECT
    DISTINCT rankings.*,
    CASE
        WHEN 
            user_types.id = 3
        THEN @aId
        WHEN
            user_types.id in (2, 5, 6)
        THEN @bId
        WHEN
            user_types.id in (1, 4, 7)
        THEN @cId
        WHEN 
            user_types.id = 8
        THEN @dId
        ELSE @eId
    END AS ranking_type_id
FROM
    `db`.rankings
RIGHT JOIN
    `db`.user_types
  ON
    rankings.user_id = user_types.id
WHERE
    rankings_term_id = 8
ORDER BY 
    rankings.group_id,
    ranking_type_id,
    rankings.rank
;

たしかに!!!
WHENの中にIN使う発想がなかった。

こういう、同一内容のORがあったら、IN疑うのは良いことですね!

最後に、全体を整えるー

最終型

SET @aId = 5, @bId = 6, @cId = 7, @dId = 8, @eId = 0;

SELECT DISTINCT
    rankings.*,
    CASE
        WHEN 
            user_types.id = 3
        THEN @aId
        WHEN
            user_types.id IN (2, 5, 6)
        THEN @bId
        WHEN
            user_types.id IN (1, 4, 7)
        THEN @cId
        WHEN 
            user_types.id = 8
        THEN @dId
        ELSE @eId
    END AS ranking_type_id
FROM
    `db`.rankings
RIGHT JOIN
    `db`.user_types
  ON
    rankings.user_id = user_types.id
WHERE
    rankings_term_id = 8
ORDER BY 
    rankings.group_id,
    ranking_type_id,
    rankings.rank
;

DISTINCTはSELECTのオプション、全体にかかっているので位置を移動。
INを大文字に

最初と比べても、印象はかなり変わったのではないでしょうか?

改行、インデントだけでなく、句の使い方にも工夫がありましたね。

こういう細かなテクニックの積み重ねで、キレイなコードは生まれると思います!
たまに自身のコードを、複数人で見直してみてはいかがでしょうか(‘ω‘ )!