SQLとは?
SQL(Structured Query Language)は、リレーショナルデータベースを操作するための標準言語です。 データの検索・挿入・更新・削除を行うことができます。
SELECT
INSERT
UPDATE
DELETE
SELECT - データ取得
基本形:SELECT 列名 FROM テーブル名
-- 全カラム取得
SELECT * FROM users;
-- 特定カラムのみ
SELECT name, email FROM users;
-- エイリアス(別名)
SELECT name AS 氏名, email AS メール
FROM users;
● * は全カラム(本番では非推奨)
● 必要なカラムだけ指定するのがベスト
WHERE - 条件絞り込み
-- 比較演算子
SELECT * FROM users WHERE age >= 20;
SELECT * FROM users WHERE status = 'active';
-- 複数条件(AND / OR)
SELECT * FROM users
WHERE age >= 20 AND status = 'active';
-- IN(複数値マッチ)
SELECT * FROM users
WHERE department IN ('営業', '開発', '人事');
-- LIKE(パターンマッチ)
SELECT * FROM users WHERE name LIKE '田%';
-- % = 任意の文字列, _ = 任意の1文字
比較演算子
= != < > <= >=
NULL判定
IS NULL / IS NOT NULL
ORDER BY / LIMIT
-- 昇順ソート(ASC = デフォルト)
SELECT * FROM users ORDER BY created_at;
-- 降順ソート
SELECT * FROM users ORDER BY created_at DESC;
-- 複数カラムでソート
SELECT * FROM users
ORDER BY department, name;
-- 上位N件のみ取得
SELECT * FROM users
ORDER BY score DESC LIMIT 10;
-- ページング(11件目から10件)
SELECT * FROM users
ORDER BY id LIMIT 10 OFFSET 10;
ASC(昇順)
DESC(降順)
JOIN - テーブル結合
A
users
JOIN
B
orders
-- INNER JOIN(両方に存在するデータ)
SELECT u.name, o.order_date
FROM users u
INNER JOIN orders o ON u.id = o.user_id;
-- LEFT JOIN(左テーブル全件+右の一致分)
SELECT u.name, o.order_date
FROM users u
LEFT JOIN orders o ON u.id = o.user_id;
INNER JOIN
共通部分のみ
LEFT JOIN
左テーブル基準
GROUP BY - 集計
-- 部署ごとの人数
SELECT department, COUNT(*) AS 人数
FROM users
GROUP BY department;
-- 集計結果の絞り込み(HAVING)
SELECT department, AVG(salary) AS 平均給与
FROM users
GROUP BY department
HAVING AVG(salary) > 500000;
主要な集計関数
COUNT
件数
SUM
合計
AVG
平均
MAX
最大値
MIN
最小値
DISTINCT
重複除外
サブクエリ
クエリの中にクエリを入れる。括弧 () で囲む。
-- WHERE句でサブクエリ
SELECT * FROM users
WHERE department_id IN (
SELECT id FROM departments
WHERE location = '東京'
);
-- FROM句でサブクエリ(派生テーブル)
SELECT dept, avg_salary
FROM (
SELECT department AS dept,
AVG(salary) AS avg_salary
FROM users
GROUP BY department
) AS dept_stats
WHERE avg_salary > 400000;
INSERT / UPDATE / DELETE - データ操作
INSERT(挿入)
-- 単一行挿入
INSERT INTO users
(name, email, age)
VALUES
('田中太郎',
'tanaka@example.com',
30);
-- 複数行挿入
INSERT INTO users
(name, email) VALUES
('佐藤', 'sato@ex.com'),
('鈴木', 'suzuki@ex.com');
UPDATE(更新)
-- 条件付き更新
UPDATE users
SET status = 'inactive',
updated_at = NOW()
WHERE last_login <
'2024-01-01';
-- 全件更新(危険!)
UPDATE users
SET is_verified = true;
WHERE忘れに注意!
DELETE(削除)
-- 条件付き削除
DELETE FROM users
WHERE status = 'deleted'
AND created_at <
'2023-01-01';
-- 全件削除(危険!)
DELETE FROM users;
-- または
TRUNCATE TABLE users;
本番では要注意!
実務で役立つTips
インデックス
WHERE, JOIN, ORDER BYで使うカラムにはインデックスを検討
EXPLAIN
クエリの前にEXPLAINをつけて実行計画を確認
SQLインジェクション対策
プレースホルダ(?や:name)を使い、文字列結合でSQL組み立てない
トランザクション
複数の更新はBEGIN〜COMMITで囲む
SQLの実行順序
1
FROM
2
WHERE
3
GROUP BY
4
HAVING
5
SELECT
6
ORDER BY
7
LIMIT
書く順番と実行順序は異なります。SELECTで定義したエイリアスはWHEREでは使えません。
ビジネスでよく使うパターン
月別売上集計
SELECT
DATE_FORMAT(order_date, '%Y-%m') AS 年月,
COUNT(*) AS 注文数,
SUM(amount) AS 売上合計
FROM orders
WHERE order_date >= '2024-01-01'
GROUP BY DATE_FORMAT(order_date, '%Y-%m')
ORDER BY 年月;
ランキング取得
SELECT
name,
sales,
RANK() OVER (ORDER BY sales DESC) AS 順位
FROM employees
ORDER BY 順位
LIMIT 10;
重複データの検出
SELECT email, COUNT(*) AS cnt
FROM users
GROUP BY email
HAVING COUNT(*) > 1;
CASE式で条件分岐
SELECT name,
CASE
WHEN age < 20 THEN '10代'
WHEN age < 30 THEN '20代'
WHEN age < 40 THEN '30代'
ELSE '40代以上'
END AS 年代
FROM users;