27
27

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

「このSQL、何をやっているかわかりますか?」

レビュー依頼を出したとき、先輩エンジニアから返ってきたのはこの一言でした。自分では完璧だと思っていたコードが、他人から見れば解読困難な暗号のようなものだったのです。

image.png

その原因は WITH句 を知らなかったこと。たったこれだけの知識不足が、チーム全体に迷惑をかけました。

この記事では、WITH句を知らなかったことで起きた失敗と、基本知識を体系的に学ぶ重要性についてお話しします。

WITH句を知らなかった時の失敗談

複雑化するサブクエリ地獄

当時、私は社員データの集計機能を開発していました。要件はシンプルです:

「各部署の平均給与と、その部署に所属する社員一覧を表示する」

WITH句を知らなかった私は、サブクエリをネストさせたSQLを書きました:

SELECT 
    e.name,
    e.department,
    e.salary,
    dept_avg.avg_salary
FROM 
    employees e
INNER JOIN (
    SELECT 
        department,
        AVG(salary) as avg_salary
    FROM 
        employees
    GROUP BY 
        department
) dept_avg ON e.department = dept_avg.department
WHERE 
    e.department IN (
        SELECT department 
        FROM employees 
        GROUP BY department 
        HAVING COUNT(*) >= 5
    )
ORDER BY 
    e.department, e.salary DESC;

このSQLの問題点:

  • カッコの対応がわかりにくい
  • 同じテーブルを何度もスキャンしている
  • 何を取得しているのか理解するのに時間がかかる

チームへの影響

このコードをプルリクエストに上げた結果:

image.png

先輩から「WITH句って知ってる?」と聞かれたのは、この時が初めてでした。

WITH句を使うとどうなるか

WITH句の基本

WITH句は、一時的な名前付きテーブルを定義できる機能です。複雑なSQLを段階的に、わかりやすく書けます。

基本構文:

WITH テーブル名 AS (
    SELECT ...
)
SELECT * FROM テーブル名;

先ほどのSQLをWITH句で書き直すと

WITH 
    -- 部署ごとの平均給与を計算
    dept_avg AS (
        SELECT 
            department,
            AVG(salary) as avg_salary
        FROM 
            employees
        GROUP BY 
            department
    ),
    -- 5人以上の部署を抽出
    large_depts AS (
        SELECT department
        FROM employees
        GROUP BY department
        HAVING COUNT(*) >= 5
    )
-- メインクエリ:結果を結合
SELECT 
    e.name,
    e.department,
    e.salary,
    d.avg_salary
FROM 
    employees e
INNER JOIN 
    dept_avg d ON e.department = d.department
INNER JOIN 
    large_depts ld ON e.department = ld.department
ORDER BY 
    e.department, e.salary DESC;

何が変わったか:

  • 各処理に名前がついて、何をしているか一目でわかる
  • カッコのネストがなく、上から順に読める
  • 各CTEを個別にテストできて、デバッグが簡単

実際、このバージョンは先輩から「これならすぐ理解できる」と即承認されました。

WITH句のメリット

複雑なクエリを段階的に構築

  • 大きな問題を小さなステップに分解
  • 各ステップを独立して検証できる

可読性とメンテナンス性

  • レビュアーが理解しやすい
  • 修正箇所が明確
  • 新メンバーもコードを追いやすい

デバッグが簡単

-- 途中結果を確認したいとき
WITH 
    dept_avg AS (...)
-- ここで確認できる
SELECT * FROM dept_avg;

WITH句使用時の注意点

WITH句は便利ですが、いくつか注意点もあります:

パフォーマンス

  • CTEは実行のたびに計算される場合がある
  • PostgreSQL 12以降では MATERIALIZED でキャッシュ可能

対応DB

  • PostgreSQL、MySQL 8.0以降、Oracle、SQL Serverなどで利用可能
  • 古いバージョンでは未対応の場合も

基本知識の重要性を痛感

なぜ基礎を学び直そうと思ったか

WITH句の件をきっかけに、自分の学習方法を見直しました。

気づいたこと:

  • ネットで調べて「動くコード」は書けていた
  • でも、SQLの基本機能を体系的に理解していなかった
  • 知らない機能が多すぎて、最適な解決方法を選べていなかった

実は、WITH句以外にも知らなかった便利な機能がたくさんありました:

  • ウィンドウ関数
  • LATERAL JOIN
  • GROUPING SETS、ROLLUP、CUBE
  • インデックスの種類と使い分け

断片的に学ぶのではなく、データベースの基本を一度しっかり学び直す必要性を強く感じました。

また、基礎知識はチーム開発における共通言語だと気づきました。技術的な会話についていけず、レビューコメントの意図を理解するのにも時間がかかっていました。

OSS-DB技術者認定試験への挑戦

そこで選んだのが、OSS-DB技術者認定試験でした。

image.png

OSS-DBは PostgreSQL の技術力と知識を認定する資格です。私はまず Silver から挑戦しました。

OSS-DB試験の良いところ:

出題範囲が明確で、体系的に学べる:

  • SQL全般:WITH句、ウィンドウ関数、トランザクション制御
  • データベース設計:正規化、制約、トリガー
  • 運用管理:バックアップ、リストア
  • パフォーマンス:インデックス、EXPLAIN ANALYZE

これらの知識は PostgreSQL に限らず、他のリレーショナルデータベースでも応用できる普遍的なものです。

試験勉強を通じて得られたもの:

  • SQLを書くときの選択肢が増えた
  • パフォーマンス問題の原因を特定しやすくなった
  • 技術的な議論についていけるようになった
  • 「なんとなく」ではなく理解してコードを書けるようになった

OSS-DB試験の詳細は公式サイトをご確認ください:

※試験内容や受験料は変更される可能性がありますので、最新情報は公式サイトでご確認ください。

まとめ

SQLの基礎知識に不安がある方は、OSS-DB試験での学習をおすすめします。試験合格が目的ではなく、体系的に学ぶためのガイドとして活用するだけでも、実務で大きな違いを生むはずです。

「あの時WITH句を知っていれば」という後悔を、これから学ぶ皆さんには味わってほしくありません。基礎を固めて、自信を持ってSQLを書けるエンジニアを目指しましょう!

参考リンク

27
27
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
27

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?