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