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を大文字に
最初と比べても、印象はかなり変わったのではないでしょうか?
改行、インデントだけでなく、句の使い方にも工夫がありましたね。
こういう細かなテクニックの積み重ねで、キレイなコードは生まれると思います!
たまに自身のコードを、複数人で見直してみてはいかがでしょうか(‘ω‘ )!