SQL基本コマンド集
データ操作編
8. データ挿入(INSERT)
基本的なINSERT
-- 全カラムに値を指定
INSERT INTO users VALUES (1, 'Tanaka', 'tanaka@example.com', 25, NOW());
-- 特定のカラムに値を指定(推奨)
INSERT INTO users (name, email, age)
VALUES ('Tanaka', 'tanaka@example.com', 25);
-- 一部のカラムのみ指定(他はNULLまたはデフォルト値)
INSERT INTO users (name, email)
VALUES ('Suzuki', 'suzuki@example.com'); 複数行の一括挿入
-- 複数行を同時に挿入
INSERT INTO users (name, email, age) VALUES
('Tanaka', 'tanaka@example.com', 25),
('Suzuki', 'suzuki@example.com', 30),
('Sato', 'sato@example.com', 28);
-- パフォーマンスが良い(個別にINSERTするより高速) SELECT結果からの挿入
-- 別テーブルからデータをコピー
INSERT INTO users_backup (name, email, age)
SELECT name, email, age FROM users WHERE age >= 20;
-- 集計結果を挿入
INSERT INTO category_stats (category, product_count, avg_price)
SELECT category, COUNT(*), AVG(price)
FROM products
GROUP BY category; 重複時の処理(MySQL)
-- 重複していたら更新(MySQL)
INSERT INTO users (id, name, email, age)
VALUES (1, 'Tanaka', 'tanaka@example.com', 26)
ON DUPLICATE KEY UPDATE
name = VALUES(name),
age = VALUES(age);
-- 重複していたら無視
INSERT IGNORE INTO users (id, name, email)
VALUES (1, 'Tanaka', 'tanaka@example.com'); UPSERT(PostgreSQL)
-- PostgreSQLの場合
INSERT INTO users (id, name, email, age)
VALUES (1, 'Tanaka', 'tanaka@example.com', 26)
ON CONFLICT (id) DO UPDATE
SET name = EXCLUDED.name,
age = EXCLUDED.age;
-- 重複時は何もしない
INSERT INTO users (id, name, email)
VALUES (1, 'Tanaka', 'tanaka@example.com')
ON CONFLICT (id) DO NOTHING; 9. データ更新(UPDATE)
基本的なUPDATE
-- 1つのカラムを更新
UPDATE users
SET age = 26
WHERE id = 1;
-- 複数のカラムを更新
UPDATE users
SET age = 26, email = 'newemail@example.com'
WHERE id = 1;
-- 警告: WHERE句を省略すると全行が更新される!
UPDATE users SET age = 0; -- 全ユーザーのageが0に! 条件付きUPDATE
-- 複数条件
UPDATE products
SET price = price * 0.9
WHERE category = 'electronics' AND stock > 10;
-- 計算結果を使う
UPDATE products
SET price = price * 1.1
WHERE category = 'books';
-- 現在値を使った更新
UPDATE products
SET stock = stock - 1
WHERE id = 100; CASE式を使った条件分岐更新
-- 条件によって異なる値を設定
UPDATE products
SET price = CASE
WHEN category = 'electronics' THEN price * 1.1
WHEN category = 'books' THEN price * 1.05
ELSE price
END
WHERE stock > 0; JOINを使ったUPDATE(MySQL)
-- 他のテーブルの値を使って更新
UPDATE orders o
JOIN users u ON o.user_id = u.id
SET o.status = 'vip_processing'
WHERE u.membership = 'premium'; JOINを使ったUPDATE(PostgreSQL)
-- PostgreSQLの構文
UPDATE orders
SET status = 'vip_processing'
FROM users
WHERE orders.user_id = users.id
AND users.membership = 'premium'; 10. データ削除(DELETE)
基本的なDELETE
-- 条件に一致する行を削除
DELETE FROM users WHERE id = 1;
-- 複数条件
DELETE FROM products
WHERE stock = 0 AND created_at < '2025-01-01';
-- 警告: WHERE句を省略すると全行が削除される!
DELETE FROM users; -- 全ユーザーが削除される! サブクエリを使ったDELETE
-- 注文がないユーザーを削除
DELETE FROM users
WHERE id NOT IN (
SELECT DISTINCT user_id FROM orders WHERE user_id IS NOT NULL
);
-- 1年以上前のデータを削除
DELETE FROM logs
WHERE created_at < DATE_SUB(NOW(), INTERVAL 1 YEAR); JOINを使ったDELETE(MySQL)
-- 他のテーブルを参照して削除
DELETE o
FROM orders o
JOIN users u ON o.user_id = u.id
WHERE u.status = 'deleted'; TRUNCATE(全削除)
-- テーブルの全データを削除(高速)
TRUNCATE TABLE logs;
-- DELETEとの違い:
-- - TRUNCATEは高速(ロールバック不可の場合あり)
-- - WHERE句が使えない
-- - AUTO_INCREMENTはリセットされる
-- - トリガーが発火しない DELETEとTRUNCATEの比較
-- DELETE: 条件指定可能、ロールバック可能、遅い
DELETE FROM users WHERE status = 'inactive';
-- TRUNCATE: 全削除のみ、高速、AUTO_INCREMENTリセット
TRUNCATE TABLE users; 11. トランザクション
基本的なトランザクション
-- トランザクション開始
START TRANSACTION;
-- または
BEGIN;
-- 複数の操作を実行
UPDATE accounts SET balance = balance - 1000 WHERE id = 1;
UPDATE accounts SET balance = balance + 1000 WHERE id = 2;
-- 全て成功したらコミット
COMMIT;
-- エラーがあったらロールバック
ROLLBACK; トランザクションの実用例
-- 銀行口座間の送金
START TRANSACTION;
-- 送金元から引き落とし
UPDATE accounts
SET balance = balance - 10000
WHERE id = 1 AND balance >= 10000;
-- 引き落としに失敗したかチェック
SELECT ROW_COUNT() INTO @affected;
IF @affected = 0 THEN
ROLLBACK;
SELECT '残高不足' AS error;
ELSE
-- 送金先に加算
UPDATE accounts
SET balance = balance + 10000
WHERE id = 2;
COMMIT;
SELECT '送金完了' AS message;
END IF; SAVEPOINT(セーブポイント)
-- トランザクションの一部だけをロールバック
START TRANSACTION;
INSERT INTO users (name, email) VALUES ('User1', 'user1@example.com');
-- セーブポイントを作成
SAVEPOINT sp1;
INSERT INTO users (name, email) VALUES ('User2', 'user2@example.com');
-- エラーがあったらsp1までロールバック
ROLLBACK TO SAVEPOINT sp1;
-- User1の挿入は有効、User2はキャンセルされる
COMMIT; トランザクション分離レベル
-- 分離レベルの設定(MySQL)
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; -- MySQLデフォルト
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
-- レベルの特徴:
-- READ UNCOMMITTED: ダーティリード発生(最も低い分離)
-- READ COMMITTED: コミット済みデータのみ読む
-- REPEATABLE READ: 同じトランザクション内で一貫した読み取り
-- SERIALIZABLE: 最も高い分離(最も遅い) トランザクションの基本原則(ACID)
- Atomicity(原子性): 全て成功するか、全て失敗するか
- Consistency(一貫性): データベースの整合性を保つ
- Isolation(独立性): 他のトランザクションから独立
- Durability(永続性): コミット後はデータが永続化される