SQLとは何か?
SQL(Structured Query Language、構造化問い合わせ言語)は、リレーショナルデータベースを操作するための標準言語です。1970年代にIBMで開発されて以来、半世紀近く現役で使われ続けている、Webアプリケーションのバックエンドでは欠かせない技術です。
MySQL、PostgreSQL、SQLite、Oracle、SQL Serverなど、多くのRDBMS(リレーショナルデータベース管理システム)が共通の文法でSQLを使えるため、一度覚えれば長く役立ちます。
テーブルの基礎
リレーショナルデータベースでは、データはテーブル(表)として管理されます。例えば「ユーザー一覧」のテーブルは以下のようなイメージです:
| id | name | age | |
|---|---|---|---|
| 1 | 田中太郎 | [email protected] | 30 |
| 2 | 鈴木花子 | [email protected] | 25 |
| 3 | 佐藤次郎 | [email protected] | 42 |
各列(カラム)には型があり、各行(レコード)がデータの1件分を表します。
テーブルの作成(CREATE TABLE)
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
age INT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
この例で押さえておきたいキーワード:
PRIMARY KEY:行を一意に識別する主キーAUTO_INCREMENT:自動的に連番が振られるNOT NULL:NULLを許容しないUNIQUE:重複を許容しないDEFAULT:未指定時のデフォルト値
SELECT:データの取得
SQLで最もよく使うのが SELECT 文です。
-- 全件取得(非推奨:本番では避ける)
SELECT * FROM users;
-- 特定の列だけ取得
SELECT name, email FROM users;
-- 条件で絞り込み
SELECT * FROM users WHERE age >= 30;
-- 並べ替え
SELECT * FROM users ORDER BY age DESC;
-- 件数制限
SELECT * FROM users LIMIT 10;
WHERE句で使える演算子
-- 等しい
WHERE age = 30
-- 範囲
WHERE age BETWEEN 20 AND 40
-- リスト
WHERE id IN (1, 3, 5)
-- パターンマッチ(%は任意の文字列、_は1文字)
WHERE name LIKE '田%' -- 「田」で始まる
WHERE email LIKE '%@gmail.com'
-- NULL判定
WHERE age IS NULL
WHERE age IS NOT NULL
-- 複合条件
WHERE age >= 20 AND name LIKE '田%'
WHERE age < 18 OR age > 65
SELECT *は便利ですが、本番のクエリでは必要なカラムだけを明示的に書きましょう。不要なデータ転送を減らせるうえ、テーブル構造の変更にも強くなります。INSERT・UPDATE・DELETE
INSERT(挿入)
-- 1件挿入
INSERT INTO users (name, email, age)
VALUES ('山田太郎', '[email protected]', 28);
-- 複数件まとめて挿入
INSERT INTO users (name, email, age) VALUES
('Aさん', '[email protected]', 22),
('Bさん', '[email protected]', 35),
('Cさん', '[email protected]', 40);
UPDATE(更新)
-- 特定行の更新(必ずWHEREを書く!)
UPDATE users
SET age = 31, email = '[email protected]'
WHERE id = 1;
WHEREを書き忘れると全行が書き換えられます。本番DBで実行する前は必ず確認してください。多くのDBクライアントには「セーフモード」(WHEREなしのUPDATE/DELETEを禁止する設定)があります。DELETE(削除)
-- 特定行の削除
DELETE FROM users WHERE id = 5;
-- 条件に合うすべての行を削除
DELETE FROM users WHERE age < 18;
JOIN:テーブルの結合
実際のシステムでは、データは複数のテーブルに分かれて格納されています。例えば「ユーザー」と「投稿」を別テーブルにして、関連付けで管理するのが一般的です。
-- usersテーブルとpostsテーブル
-- posts.user_id が users.id を参照する
-- INNER JOIN:両方に存在するデータのみ取得
SELECT users.name, posts.title
FROM users
INNER JOIN posts ON users.id = posts.user_id;
-- LEFT JOIN:左側のテーブルは全件、右側は一致するもの
SELECT users.name, posts.title
FROM users
LEFT JOIN posts ON users.id = posts.user_id;
-- 投稿がないユーザーも結果に含まれる(postsの列はNULL)
JOINの種類まとめ
| 種類 | 結果 |
|---|---|
| INNER JOIN | 両方のテーブルに一致するレコードのみ |
| LEFT JOIN | 左テーブル全件 + 右テーブルの一致分(無ければNULL) |
| RIGHT JOIN | 右テーブル全件 + 左テーブルの一致分 |
| FULL OUTER JOIN | 両方のテーブル全件(一致しない部分はNULL) |
集計:GROUP BY と集計関数
「ユーザーごとの投稿数」「年齢別の平均値」のような集計にはGROUP BYを使います。
-- 主な集計関数
SELECT
COUNT(*) AS total, -- 件数
AVG(age) AS avg_age, -- 平均
SUM(age) AS sum_age, -- 合計
MAX(age) AS max_age, -- 最大
MIN(age) AS min_age -- 最小
FROM users;
-- グループ化して集計
SELECT user_id, COUNT(*) AS post_count
FROM posts
GROUP BY user_id
ORDER BY post_count DESC;
-- HAVING で集計後の絞り込み
SELECT user_id, COUNT(*) AS post_count
FROM posts
GROUP BY user_id
HAVING COUNT(*) >= 5;
WHEREは集計前の絞り込み、HAVINGは集計後の絞り込みです。混同しがちなのでセットで覚えましょう。インデックス:高速化の鍵
テーブルに大量データが入ってくると、検索が遅くなります。インデックス(索引)を貼ることで、特定カラムでの検索を劇的に速くできます。
-- インデックス作成
CREATE INDEX idx_users_email ON users(email);
-- 複合インデックス(複数カラム)
CREATE INDEX idx_posts_user_date ON posts(user_id, created_at);
-- インデックス削除
DROP INDEX idx_users_email ON users;
インデックスの注意点
- 検索は速くなるが、INSERT/UPDATE/DELETEは遅くなる(索引も更新が必要なため)
- すべての列に貼ればいいわけではない。WHERE/JOIN/ORDER BYで使う列に貼る
- カーディナリティ(値のばらつき)が高い列ほど効果が大きい(性別など2値しかないものは効果薄)
トランザクション
「複数のSQLをまとめて、すべて成功するか、すべて失敗扱いにするか」を実現するのがトランザクションです。
BEGIN; -- トランザクション開始
UPDATE accounts SET balance = balance - 1000 WHERE id = 1;
UPDATE accounts SET balance = balance + 1000 WHERE id = 2;
-- 全部成功なら確定
COMMIT;
-- どこかで失敗したら巻き戻し
-- ROLLBACK;
送金のように「片方だけ成功すると整合性が壊れる」処理では必須です。
SQL学習を効率化する3つのコツ
- 手を動かす:SQLite(インストール簡単)やDBeaver(GUIクライアント)で実際に動かす
- EXPLAINを読む:クエリの実行計画を確認する習慣をつけると、遅いクエリの原因が見えるようになる
- サブクエリよりJOINを優先:可読性とパフォーマンスの両面で有利になることが多い
まとめ
- SELECT:データ取得の基本。WHERE、ORDER BY、LIMITを組み合わせる
- INSERT/UPDATE/DELETE:データ操作。WHEREの書き忘れに注意
- JOIN:複数テーブルを関連付けて取得。INNERとLEFTの違いを理解する
- GROUP BY:集計の基本。HAVINGで集計後の絞り込み
- インデックス:検索高速化の要。貼りすぎは逆効果
- トランザクション:整合性が必要な処理で必須
SQLは奥深い言語ですが、まずは基本のSELECT・JOIN・GROUP BYを使いこなせるようになるだけで実務の8割はカバーできます。次はあなたの好きなRDBMSをインストールして、実際に手を動かしてみましょう!