SQL(Structured Query Language)は、リレーショナルデータベースを操作するための共通言語だ。データ分析、Webアプリ、業務システム、AI/機械学習のデータ前処理まで、データに触れるあらゆる現場で必須のスキルになっている。
本記事では、SQLの基本を「最低限これだけ押さえれば実務で動ける」という観点で整理する。SELECT文の構文、WHERE句、集計関数、GROUP BY、JOIN、サブクエリといった実務頻出の文法を、コード例つきでまとめた。
- SELECT/WHERE/ORDER BY/LIMITなどSQLの基本構文を実例つきで整理
- GROUP BY・HAVING・JOIN・サブクエリといった実務頻出パターンを総まとめ
- SQLの論理的な実行順序と、初心者が必ずハマる落とし穴の対処法
- 基本の次に学ぶべきウィンドウ関数・CTE・パフォーマンスの地図
SQLとは

SQLは、リレーショナルデータベース管理システム(RDBMS)を操作するための問い合わせ言語だ。データの取得・追加・更新・削除(CRUD)をすべて文字列のコマンドで指示できるのが特徴で、PostgreSQL、MySQL、SQL Server、Oracle、SQLite、Snowflake、BigQueryなど、ほぼすべての主要RDBMSで共通して使える。
SQLが書ける人材の市場価値
データエンジニア、データアナリスト、マーケティングエンジニア、バックエンドエンジニアなど、「データを扱う仕事」の入口になっている。求人要件としても出現頻度が高く、「SQLが書ける/書けない」で初動の生産性が大きく変わる。
方言(SQLダイアレクト)の存在
SQLは標準仕様(ISO/JIS)があるが、RDBMSごとに少しずつ方言(ダイアレクト)がある。本記事では標準SQLに近い書き方を採用し、必要に応じてMySQL/PostgreSQLの差分を補足する。
- データ分析・Web・業務システム・AI前処理まで、ほぼあらゆる現場で必要
- 主要RDBMS(MySQL/PostgreSQL/BigQuery/Snowflake)でほぼ共通の文法
- 方言(ダイアレクト)は存在するが、まずは標準SQLで書ける状態を作ればOK
学習用のサンプルテーブル
以下の2テーブルを例に、本記事のコードは記述する。実務でも頻出する「ユーザー」「注文」を例にとった。
usersテーブル
| id | name | age | prefecture |
|---|---|---|---|
| 1 | 佐藤 | 34 | 東京都 |
| 2 | 鈴木 | 28 | 大阪府 |
| 3 | 高橋 | 45 | 東京都 |
| 4 | 田中 | 22 | 福岡県 |
ordersテーブル
| id | user_id | amount | ordered_at |
|---|---|---|---|
| 101 | 1 | 3000 | 2026-04-01 |
| 102 | 1 | 5000 | 2026-04-15 |
| 103 | 2 | 1500 | 2026-04-20 |
| 104 | 3 | 8000 | 2026-04-25 |
SELECT文の基本構文
SQLでデータを取得するには、SELECT文を使う。最小構成は次の3つ。
- SELECT(必須):取得したい列を指定
- FROM(必須):対象テーブルを指定
- WHERE(任意):取得するデータの条件を指定。指定しなければ全行取得
最もシンプルな例
SELECT id, name, age
FROM users;
WHERE句で条件を絞り込む
WHERE句で特定の条件に合致する行だけを取り出せる。
SELECT name, age
FROM users
WHERE age >= 30;
複数条件:AND/OR
AND は両方を満たす、OR はいずれかを満たす行を返す。
SELECT name, age, prefecture
FROM users
WHERE prefecture = '東京都'
AND age >= 30;
BETWEEN/IN/LIKE
実務でよく使う比較演算子は次の3つ。
- BETWEEN A AND B:値がAとBの間(A・Bを含む)
- IN (a, b, c):値が指定リストのいずれか
- LIKE ‘%山田%’:あいまい検索(%は0文字以上の任意の文字列)
-- 30〜40歳の東京都/大阪府ユーザー
SELECT *
FROM users
WHERE age BETWEEN 30 AND 40
AND prefecture IN ('東京都', '大阪府');
並び替え(ORDER BY)と件数制限(LIMIT)
取得結果の並び順を制御するのがORDER BY、件数を制限するのがLIMIT(SQL Serverでは TOP、OracleではFETCH FIRST)。
SELECT name, age
FROM users
ORDER BY age DESC
LIMIT 3;
DESCは降順、ASCは昇順(既定)。「年齢が高い順に上位3名を取得」という、現場で頻出のクエリだ。
集計関数とGROUP BY
集計関数は、複数行のデータを1つの値にまとめる関数。覚えるのは5つで十分だ。
- COUNT:件数
- SUM:合計
- AVG:平均
- MIN:最小
- MAX:最大
-- 全ユーザー数
SELECT COUNT(*) AS user_count
FROM users;
-- 全注文の合計金額・平均金額
SELECT SUM(amount) AS total,
AVG(amount) AS avg_amount
FROM orders;
GROUP BYでグループ別に集計
GROUP BYで指定したカラムごとにデータをまとめ、各グループに対して集計関数を適用できる。
-- 都道府県ごとのユーザー数
SELECT prefecture, COUNT(*) AS user_count
FROM users
GROUP BY prefecture;
-- ユーザーごとの合計購入金額
SELECT user_id, SUM(amount) AS total_amount
FROM orders
GROUP BY user_id;
重要なルール:集計関数(SUM/COUNT等)以外のカラムは、原則すべてGROUP BYに含めなければならない。これを忘れて怒られるのは初心者あるあるだ。
HAVING:集計後の条件絞り込み
WHEREは集計前の行に対する条件、HAVINGは集計後の結果に対する条件、と覚える。
-- 合計購入金額が5000円以上のユーザーだけ抽出
SELECT user_id, SUM(amount) AS total_amount
FROM orders
GROUP BY user_id
HAVING SUM(amount) >= 5000;
JOIN:テーブルの結合
JOINは実務で最も頻繁に使い、最もハマりやすい領域だ。INNER/LEFT の2つを正しく使い分けられれば、現場のクエリの大半は書ける。RIGHT や FULL OUTER は出番が少ないので、後回しでOK。
複数のテーブルを共通のキーでつないで1つの結果セットにする操作がJOINだ。実務で最も頻繁に使う中で、最もハマりやすい部分でもある。
INNER JOIN(内部結合)
両方のテーブルに一致する行がある場合のみ結果に残す。最もよく使う結合形式だ。
SELECT u.name, o.amount, o.ordered_at
FROM users AS u
INNER JOIN orders AS o
ON u.id = o.user_id;
AS u、AS oはテーブルの別名(エイリアス)。複数テーブルを扱うときに必須の記法だ。
LEFT JOIN(左外部結合)
左側のテーブルの行は一致しなくてもすべて残す。右側のテーブルに対応行がない場合はNULLが入る。
-- 「注文がないユーザー」も含めて全ユーザーを取得
SELECT u.name, o.amount
FROM users AS u
LEFT JOIN orders AS o
ON u.id = o.user_id;
用途の例:全顧客のうち、注文経験がない人を洗い出す(WHERE o.id IS NULL を追加)。
RIGHT JOIN/FULL OUTER JOIN
RIGHT JOINは右テーブル基準、FULL OUTER JOINは両方の行を残す結合。実務での出現頻度はINNER/LEFTの方が圧倒的に高い。RIGHT JOINは、テーブルの順序を入れ替えてLEFT JOINで書き直すのが定石だ。
JOINの種類まとめ
| 結合の種類 | 挙動 | 使いどころ |
|---|---|---|
| INNER JOIN | 両方一致した行のみ | 正しく対応するデータだけ欲しいとき |
| LEFT JOIN | 左テーブルは全て残す | 「対応がない」も含めて確認したいとき |
| RIGHT JOIN | 右テーブルは全て残す | LEFTで書き直すのが一般的 |
| FULL OUTER JOIN | 両方の行をすべて残す | 差分検出など特殊用途 |
サブクエリ(副問い合わせ)
サブクエリとは、SELECTの結果を1つのテーブルとしてSQLの中で使う書き方だ。SELECTの中、FROMの中、WHEREの中など、さまざまな位置で使える。
WHERE句でのサブクエリ
-- 平均年齢より年上のユーザーを取得
SELECT name, age
FROM users
WHERE age > (SELECT AVG(age) FROM users);
FROM句でのサブクエリ(インラインビュー)
-- ユーザー別合計をサブクエリで作り、それを使って絞り込み
SELECT u.name, t.total_amount
FROM users AS u
INNER JOIN (
SELECT user_id, SUM(amount) AS total_amount
FROM orders
GROUP BY user_id
) AS t
ON u.id = t.user_id
WHERE t.total_amount >= 5000;
複雑なロジックを段階的に組み立てるときの定石が、このFROMサブクエリだ。読みやすさが上がり、デバッグもしやすくなる。
SQLの「論理的な実行順序」を理解する
SQLは書く順番と実行される順番が違う。これを知っていると、エラーや結果のズレに直感的に気づけるようになる。
テーブルを用意する。複数テーブルなら結合キーを決め、INNER/LEFT を選ぶ。
行を絞り込む。集計前のフィルタなので、SELECTで作ったエイリアスは原則使えない。
指定カラムでグループ化する。集計関数以外のカラムは原則すべて含める。
グループに対する条件で絞り込む。SUM/COUNT等の集計値で条件を書ける。
出力するカラムを選ぶ。AS でエイリアスを付けるのもこの段階。
並び順を確定する。SELECTで作ったエイリアスを使えるDBが多い。
最後に件数を制限する。MySQL/PostgreSQLは LIMIT、SQL Serverは TOP、Oracleは FETCH FIRST。
つまり、SELECTで作った別名(エイリアス)はWHEREでは使えない(実行が後だから)。HAVINGでは使えるDBもあるが、一貫性のためにサブクエリで包むのが安全だ。
初心者がハマりやすいポイント
- NULLの扱い:
= NULLでは比較できない(IS NULLを使う) - 大文字小文字:DBの照合順序で挙動が変わる(
LOWER()で統一) - 暗黙の型変換:
'10' = 10はDBによって動作が違う - JOINでの行増減:カーディナリティの罠で集計値が狂う
1. NULL の扱い
NULLは「値が入っていない」状態を表し、= NULL では比較できない。比較には IS NULL / IS NOT NULL を使う。
-- ✗ 取得できない
SELECT * FROM orders WHERE amount = NULL;
-- ◯ 正しい
SELECT * FROM orders WHERE amount IS NULL;
2. 文字列比較の大文字小文字
DBやカラムの照合順序によって、大文字小文字を区別する/しないの挙動が変わる。あいまい検索したいときは LOWER() / UPPER() を使うのが確実。
3. 暗黙の型変換
’10’ = 10 のように型が違うと、DBによって動作が異なる(エラー or 自動変換)。比較は同じ型にそろえる癖をつける。
4. JOINでの行の増減
複数行に対応するキーでJOINすると、意図せず行が増える(カーディナリティの罠)ことがある。集計値が想定と違うときは、まず SELECT * でJOIN直後の行数を確認するとよい。
SQLを学ぶためのおすすめリソース
「写経 → 自分のデータで書き換える → 実務で本番データに当てる」の順で進めると、定着が早い。BigQueryやSupabaseの無料枠で「自分用のテストDB」を作るのも非常におすすめだ。
- Progate「SQL」:完全初心者向けの最初の一歩。月額制でブラウザ上で書いて学べる
- paizaラーニング 新・SQL入門編:MySQLベースで基礎を独学できる
- SQLBolt:書いたSQLの結果がリアルタイムで返ってくる教材
- SQL攻略:Web上でSQLを実行しながら学べる日本語サイト
- スッキリわかる SQL 入門:図解豊富、ドリル215問付きの定番書
「写経 → 自分のデータで書き換える → 実務で本番データに当てる」の順で進めると、定着が早い。BigQueryやSupabaseの無料枠で「自分用のテストDB」を作るのも非常におすすめだ。
基本の次に学ぶべきこと
- ウィンドウ関数(ROW_NUMBER/RANK/LAG/LEAD):分析クエリで強力な武器に
- CTE(WITH句):サブクエリの代わりに使え、可読性が劇的に上がる
- インデックスとEXPLAIN:パフォーマンスを語れるようになる
- トランザクション(BEGIN/COMMIT/ROLLBACK):データ整合性の基礎
- 正規化/非正規化:テーブル設計の基本
- ウィンドウ関数(ROW_NUMBER/RANK/LAG/LEAD):分析クエリで強力な武器になる
- CTE(WITH句):サブクエリの代わりに使え、可読性が劇的に上がる
- インデックスとEXPLAIN:パフォーマンスを語れるようになる
- トランザクション:BEGIN/COMMIT/ROLLBACK。データ整合性の基礎
- 正規化/非正規化:テーブル設計の基本
基本構文を一通り押さえたら、実務のクエリを写経して自分の課題に応用するのが最短ルートだ。
まとめ
- SQLの基本はSELECT × FROM × WHERE × GROUP BY × JOIN × サブクエリに集約される
- これらを組み合わせるだけで、実務の8〜9割のクエリは書ける
- 特に重要なのは論理的な実行順序の理解とNULL/JOIN での落とし穴への対処
- 基本を固めたら、ウィンドウ関数 → CTE → パフォーマンスへと階段を上ろう
SQLの基本は、SELECT × FROM × WHERE × GROUP BY × JOIN × サブクエリに集約される。これらを組み合わせるだけで、実務のクエリの8〜9割は書ける。
とくに重要なのは、論理的な実行順序を理解することと、NULLとJOINでの行増減という2大ハマりどころに注意すること。この2点を押さえるだけで、デバッグ時間が大きく減る。
基本を一気に固めたら、ウィンドウ関数・CTE・パフォーマンス分析へと階段を上っていけば、データに対する手触りが一段深くなる。

コメント