実践課題&SQLパズルでデータベース力を鍛えよう

トランザクションやインデックス、ビューなどの基礎を学んだら、次のステップは「実践」です。この章では、現場を想定したSQL課題と、発想力を刺激するSQLパズルを紹介します。正確さ・可読性・最適化を意識しながら、ぜひ挑戦してみてください。


📝 実践課題:業務シナリオでSQLを書く

課題1:月次売上レポートを出力せよ

テーブル構成:

  • sales(id, product_id, amount, sale_date)
  • products(id, name, category)

要件:

  • 今月の売上合計をカテゴリごとに集計
  • カテゴリ名と売上合計を降順で表示
-- あなたのSQL: SELECT ... FROM ... WHERE ... GROUP BY ... ORDER BY ... DESC; 

課題2:ログインしないユーザーを抽出せよ

テーブル構成:

  • users(id, name, created_at)
  • logins(user_id, login_at)

要件:

  • 過去30日間にログインしていないユーザーを抽出
  • LEFT JOINIS NULLを活用
-- あなたのSQL: SELECT ... FROM ... LEFT JOIN ... ON ... WHERE ... 

課題3:同姓同名ユーザーの重複をチェックせよ

テーブル構成:

  • users(id, last_name, first_name)

要件:

  • 同じ名前のユーザーが2人以上いる組み合わせを表示
  • 姓・名ごとにグループ化し、件数をカウント
-- あなたのSQL: SELECT last_name, first_name, COUNT(*) as count FROM users GROUP BY last_name, first_name HAVING COUNT(*) >= 2; 

🧠 SQLパズル:ロジックで解く頭の体操

パズル1:ランク付けせよ(RANK vs ROW_NUMBER)

テーブル: players(id, name, score)

問題: スコアの高い順に順位をつけ、同スコアは同順位とし、順位の飛び番も考慮すること。

-- RANKを使った例: SELECT name, score, RANK() OVER (ORDER BY score DESC) AS rank FROM players; 

さらに応用: ROW_NUMBERとの違いを比較してみましょう。

パズル2:連続ログイン日数をカウントせよ

テーブル: logins(user_id, login_date)

問題: ユーザーごとに、連続ログインした最大日数を求めてください。

ヒント: 日付と連番を差し引いてグループ化する手法(ギャップアンドアイランド)を使います。

-- 難易度高:PostgreSQL用 SELECT user_id, COUNT(*) AS streak FROM ( SELECT user_id, login_date, login_date - INTERVAL '1 day' * ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY login_date) AS grp FROM logins ) AS t GROUP BY user_id, grp ORDER BY streak DESC; 

パズル3:カレンダーを作れ

問題: 指定月の1日〜末日までの日付を行として出力してください(テーブルに日付が存在しない場合も含む)。

ヒント: 生成関数 generate_series()(PostgreSQL)や数値テーブルとのJOINを活用します。

-- PostgreSQL用 SELECT generate_series( DATE '2025-10-01', DATE '2025-10-31', INTERVAL '1 day' ) AS calendar_day; 

MySQLの場合: 1〜31の数値テーブルをJOINして日付を作成する方法を使います。


💡 解答のチェックポイント

自分のSQLが正しいかどうかをチェックするには、次の点を意識しましょう:

  • 出力結果は要件に合っているか?
  • クエリの実行時間は許容範囲か?(特にJOINやウィンドウ関数)
  • インデックスを活用できる書き方か?
  • 可読性があるか?将来の自分が読んで理解できるか?

正解は1つではありません。「なぜその書き方をしたのか」を説明できるようになることが、エンジニアとしての実力アップに直結します。

採用情報 長谷川 横バージョン
SHARE
PHP Code Snippets Powered By : XYZScripts.com
お問い合わせ