はじめに
「このSQL、何をやっているかわかりますか?」
レビュー依頼を出したとき、先輩エンジニアから返ってきたのはこの一言でした。自分では完璧だと思っていたコードが、他人から見れば解読困難な暗号のようなものだったのです。
その原因は 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の問題点:
- カッコの対応がわかりにくい
- 同じテーブルを何度もスキャンしている
- 何を取得しているのか理解するのに時間がかかる
チームへの影響
このコードをプルリクエストに上げた結果:
先輩から「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技術者認定試験でした。
OSS-DBは PostgreSQL の技術力と知識を認定する資格です。私はまず Silver から挑戦しました。
OSS-DB試験の良いところ:
出題範囲が明確で、体系的に学べる:
- SQL全般:WITH句、ウィンドウ関数、トランザクション制御
- データベース設計:正規化、制約、トリガー
- 運用管理:バックアップ、リストア
- パフォーマンス:インデックス、EXPLAIN ANALYZE
これらの知識は PostgreSQL に限らず、他のリレーショナルデータベースでも応用できる普遍的なものです。
試験勉強を通じて得られたもの:
- SQLを書くときの選択肢が増えた
- パフォーマンス問題の原因を特定しやすくなった
- 技術的な議論についていけるようになった
- 「なんとなく」ではなく理解してコードを書けるようになった
OSS-DB試験の詳細は公式サイトをご確認ください:
※試験内容や受験料は変更される可能性がありますので、最新情報は公式サイトでご確認ください。
まとめ
SQLの基礎知識に不安がある方は、OSS-DB試験での学習をおすすめします。試験合格が目的ではなく、体系的に学ぶためのガイドとして活用するだけでも、実務で大きな違いを生むはずです。
「あの時WITH句を知っていれば」という後悔を、これから学ぶ皆さんには味わってほしくありません。基礎を固めて、自信を持ってSQLを書けるエンジニアを目指しましょう!


