※本記事はOracleユーザー向けに書いてあります。
SQLに慣れてきた?社会人3年目。
SELECT・JOIN・GROUP BYはもう普通に書ける。
でも、「なんか遅い」「意図通りの結果が出ない」と感じることが増えてくると思います
この記事では、3年目以降のSQL使いが知っておくと仕事が速く・正確になる豆知識10選を紹介します。
INNER JOIN は「両方に存在する行」を返す。
LEFT JOIN は「左テーブルの行をすべて残す」。
SELECT *
FROM EMP e
LEFT JOIN DEPT d ON e.DEPT_ID = d.DEPT_ID
WHERE d.DEPT_NAME = '営業';
この書き方、実は LEFT JOIN の意味が消えます。
WHEREで右テーブル条件を書くとINNER JOIN扱いになるためです。
✅ 正しい書き方:
SELECT *
FROM EMP e
LEFT JOIN DEPT d
ON e.DEPT_ID = d.DEPT_ID
AND d.DEPT_NAME = '営業';
ネストが深くなるSQLはメンテが辛いので避けましょう。
WITH句を使えば、部分ごとに名前を付けて分けられます。
WITH SALES_2025 AS (
SELECT * FROM SALES WHERE YEAR = 2025
)
SELECT COUNT(*)
FROM SALES_2025
WHERE AMOUNT > 100000;
● ポイント:
WITH句は「仮想テーブル」。
読みやすさ・再利用性・レビューしやすさが一気に向上します。
条件 向いてる構文
サブクエリが小さい IN
サブクエリが大きい EXISTS
IN:小さいテーブル向け
SELECT * FROM EMP
WHERE DEPT_ID IN (SELECT DEPT_ID FROM DEPT);
EXISTS:大きいテーブル向け
SELECT * FROM EMP e
WHERE EXISTS (SELECT 1 FROM DEPT d WHERE e.DEPT_ID = d.DEPT_ID);
豆知識:
EXISTS は条件成立時に即終了するため、大規模データに強いです。
SELECT AVG(SCORE) FROM TEST;
NULLは自動的に除外されるため、平均が高く出ることがあります。
✅ 対策:
SELECT AVG(COALESCE(SCORE, 0)) FROM TEST;
豆知識:
COALESCE はNULLを安全に置き換える関数。
OracleやPostgreSQLでも共通で使えるSQL標準構文です。
SQLはデフォルトでは順序を保証しません。
ORDER BYがなければ、DBの内部処理順に依存します。
SELECT * FROM EMP; -- 順序保証なし
SELECT * FROM EMP ORDER BY EMP_ID; -- 順序保証あり
SELECT *は禁止(必要な列だけ取る)
WHEREで列に関数を使わない(インデックスが効かない)
ORよりIN、INよりJOINを検討する
悪い例
WHERE TO_CHAR(REG_DATE, 'YYYYMM') = '202511'
良い例
WHERE REG_DATE >= DATE '2025-11-01'
AND REG_DATE < DATE '2025-12-01'
● ポイント:
関数をWHEREで使うと、全件スキャンになります。
インデックスを活かす書き方を意識しましょう。
NULLは集計で無視されるため、明示的に置き換える。
SELECT COALESCE(SCORE, 0) AS SCORE FROM TEST;
SELECT COALESCE(NAME, '(未登録)') AS NAME FROM USER;
豆知識:
OracleのNVLよりも、SQL標準のCOALESCEを使うと他DBでも動きます。
グループごとの順位・累積などを求めたいときに強力。
SELECT
DEPT_ID,
EMP_NAME,
RANK() OVER(PARTITION BY DEPT_ID ORDER BY SALARY DESC) AS RANK_IN_DEPT
FROM EMP;
● ポイント:
GROUP BYでは潰れてしまうデータも、
ウィンドウ関数なら「グループ単位の行ごと分析」ができます。
大規模テーブルで COUNT(*) は重くなりがち。
✅ 対策:
インデックス列をCOUNT対象にする
Oracleなら統計情報(NUM_ROWS)を活用
実行計画(EXPLAIN)で全件走査になっていないか確認
▲ 豆知識:
COUNTは“重い関数”の代表格。
必要なときだけ実行する設計にすると格段に速くなります。
同じJOIN・GROUP BYを何度も使うようなら、
**中間集計テーブル(マート)**を作るのが正解です。
CREATE MATERIALIZED VIEW SALES_SUMMARY AS
SELECT DEPT_ID, SUM(AMOUNT) AS TOTAL
FROM SALES
GROUP BY DEPT_ID;
● ポイント:
SQLをチューニングするより、「SQLを書かない構造」を作る。
| 観点 | 初級者 | 中級者 |
|---|---|---|
| クエリの目的 | とにかく動かす | 結果の意味を考える |
| JOINの理解 | なんとなく結合 | 条件の順序まで意識 |
| 集計の考え方 | 関数を使う | NULL・順序・性能を考慮 |
| 設計の視点 | クエリ単体最適化 | テーブル設計から最適化 |
SQLは「書ける」から「読める」「設計できる」へ。
3年目のいまこそ、結果の“理由”を理解するSQL力を磨く時期です。
気づけば「SQL詳しい人」として一目置かれるようになります。
今日から少しずつ、“動くSQL”から“意図を持つSQL”へ進化しましょう。