SQL チートシート

エンジニアのための実践リファレンス

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組み立てない

トランザクション

複数の更新はBEGINCOMMITで囲む

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;