こんにちは!
スマレジ・テックファームのWebエンジニアやまてと申します。
今回は『プログラミング研修でのフルボッコなコードレビューの記録 - ②SQLの基礎』ということで、昨年12月1日に入社からの2カ月で受けた社内の研修について、引き続き振り返っていきたいと思います。
スマレジ・テックファームの研修についてですが、実務未経験で採用された際には、SESでの出向先が決まるまで、社内の教育担当のWebエンジニアの方から研修をしてもらえます。
研修内容は、以下のカリキュラムで、今回の記事はこちらに沿って投稿しています。
② SQLの基礎
今回は「SQLの基礎」の課題について、 SQLのデータ取得(SELECT文)のレビュー内容に絞って、整理していきたいと思います(一番レビューで色々と指摘があったため)。
※ 他には、データ操作、テーブル操作、トランザクションの問題がありました。
課題は例えば下記のようなものでした。
「商品テーブルの内容を全て出力するSQLを作ってください」
このようにSQLの基礎文法の理解を問う問題が20問ほどあり、OKもらえるまで修正しました。
研修時は、MySQLのDockerコンテナを起動して、起動したときに生成されるDBのテーブルに対してSQL実行でデータ取得やデータ更新をしました。
※ 参考記事
それでは一部抜粋して、項目ごとにまとめたコードレビューを振り返っていきます。
※ 記事にする都合上、レビューの文面は意味が変わらない程度に編集しています。
SQLのデータ取得(SELECT文)のレビュー8選
1. 「SQLコーディングスタイルを決めましょう」
💬レビュー
SQLのコーディングルールがなくて困りますね。これで統一しましょう。
レビュー、というかレビューをする前の意識合わせですが、研修中はこちらに統一して提出しました。インターネットで調べた限りではSQLのコーディングスタイルは、どの書き方が多数派かわからず、人それぞれな印象でした。
2. 「複数取得できる場合は、かならず ORDER BY
を記載する癖をつけてください」
◀︎レビュー前
SELECT product_id, product_name, color, price, delete_flag, created_at, updated_at FROM products ;
💬レビュー
複数取得できる場合は、かならず ORDER BY
を記載してください。そうする癖をつけておくようにしてください。
▶︎レビュー後
SELECT product_id, product_name, color, price, delete_flag, created_at, updated_at FROM products ORDER BY product_id ASC ;
3. 「IN
を使って、条件を1行で書いてください」
◀︎レビュー前
SELECT product_id, product_name, color, price, delete_flag, created_at, updated_at FROM products WHERE color = '赤' OR color = '青' ORDER BY product_id ASC ;
💬レビュー
IN
を使って、条件を1行で書いてください。
▶︎レビュー後
SELECT product_id, product_name, color, price, delete_flag, created_at, updated_at FROM products WHERE color IN ( '赤', '青' ) ORDER BY product_id ASC ;
(コーディングスタイルの関係で一行になってはないですが…)
4. 「 カウント関数の中に、条件書かずに、WHERE
句に条件を記載してください」
◀︎レビュー前
SELECT COUNT( gender = '男' OR NULL ) AS '男性の人数'
💬レビュー
カウント関数の中に、条件書かずに、WHERE
句に条件を記載してください。単純なcountを使うSQLは、count(*)
が一般的です。
▶︎レビュー後
SELECT COUNT(*) AS '男性の人数' FROM members WHERE delete_flag = 0 AND gender = '男' ;
5. 「テーブル結合は基本的に JOIN ON
を用いてください」
◀︎レビュー前
SELECT SUM(sales.quantity * products.price) FROM sales, products WHERE sales.product_id = products.product_id ;
💬レビュー
JOIN ON
句結合は基本的に
JOIN ON
を用いてFROM
に複数 +WHERE
句で結合条件という記述をしない
と記載のとおり、修正してください。
▶︎レビュー後
SELECT SUM(sales.quantity * products.price) FROM sales INNER JOIN products ON sales.product_id = products.product_id ;
6. 「AS
で別名つけてください」
◀︎レビュー前
SELECT SUM(sales.quantity * products.price) FROM sales INNER JOIN products ON sales.product_id = products.product_id ;
💬レビュー
AS
で別名つけてください。
▶︎レビュー後
SELECT SUM(s.quantity * p.price) AS '売り上げの合計' FROM sales AS s INNER JOIN products AS p ON s.product_id = p.product_id ;
7. 「 関連しない条件は、JOIN
したあとに記載してください」
◀︎レビュー前
SELECT SUM(s.quantity * p.price) AS '非会員の売り上げの合計' FROM sales AS s INNER JOIN products AS p ON s.product_id = p.product_id AND s.member_id IS NULL ;
💬レビュー
INNER JOIN
の ON
句に、salesの条件があると読みにくいので、 sales の条件(s.member_id IS NULL
)は JOIN
したあとに記載してください。
▶︎レビュー後
SELECT SUM(s.quantity * p.price) AS '非会員の売り上げの合計' FROM sales AS s INNER JOIN products AS p ON s.product_id = p.product_id WHERE s.member_id IS NULL ;
8. 「GROUP BY
を使った SQL に変えてください」
◀︎レビュー前
SELECT SUM( CASE WHEN m.gender = '男' THEN s.quantity * p.price ELSE 0 END ) AS '男性会員の売り上げの合計' , SUM( CASE WHEN m.gender = '女' THEN s.quantity * p.price ELSE 0 END ) AS '女性会員の売り上げの合計' FROM sales AS s INNER JOIN products AS p ON s.product_id = p.product_id INNER JOIN members AS m ON s.member_id = m.member_id ;
💬レビュー
GROUP BY
を使ったSQLに変えてください。
▶︎レビュー後
SELECT m.gender, SUM(s.quantity * p.price) AS '売り上げの合計' FROM sales AS s INNER JOIN products AS p ON s.product_id = p.product_id INNER JOIN members AS m ON s.member_id = m.member_id GROUP BY m.gender ;
今回の記事は以上です!
正直言ってSQLのスキルは研修当時からあんまり変わってない気がする、という危機感を得られたので、それだけでも今回振り返った甲斐がありました…笑
あとそれぞれ、そのように書いた方が良い理由についても理解する必要があると思いましたので、今後の課題です。
次回、「プログラミング研修でのフルボッコなコードレビューの記録 - ③ Webアプリケーション基礎」投稿予定です。
ありがとうございました。
Webエンジニアとして、 クロノトリガー でいう 強くてニューゲーム の状態になりたい。
— やまて|Webエンジニア2年目 (@r_yamate) 2022年6月6日
と言いつつ、地道に歩んでいきます。