SQL: データ操作

倉庫の管理のようなものです — 荷受け(INSERT)、棚札の調整(UPDATE)、期限切れ商品の撤去(DELETE)、倉庫全体の空所化(TRUNCATE) — データベースのCRUD操作は日常的なデータ管理の核です。操作方法を学ぶことよりも、安全にデータを操作することの方が重要です。


1. 基本概念

概念 説明
INSERT INTO テーブルに新しいデータを挿入。単一行および複数行挿入に対応
UPDATE ... SET テーブルの既存データを変更。必ずWHEREを使用して範囲を限定
DELETE FROM テーブルから特定の行を削除。必ずWHEREを使用して範囲を限定
TRUNCATE TABLE テーブルの全データを高速にクリア。DELETEより高速だがより危険
安全な操作習慣 DELETE/UPDATEを実行する前に、SELECTで影響範囲を確認
⚠️ 重要な警告: WHEREなしのUPDATEとDELETEはテーブルのすべての行に影響します!これは初心者が最もよく犯す壊滅的なミスです。



2. 基本構文

(1) INSERT INTO — データの挿入

SQL
-- 単一行を挿入(列を指定)
INSERT INTO テーブル名 (カラム1, カラム2, カラム3)
VALUES (値1, 値2, 値3);

-- 単一行を挿入(すべての列、テーブル作成順)
INSERT INTO テーブル名
VALUES (値1, 値2, 値3);

-- 複数行を挿入
INSERT INTO テーブル名 (カラム1, カラム2)
VALUES (値1, 値2),
       (値3, 値4),
       (値5, 値6);
💡 ヒント: 必ず列名を指定することを強く推奨します。 デフォルトの列順序に依存しないでください。テーブル構造が変更された場合(新しい列が追加されるなど)、列名なしのINSERTステートメントはエラーや誤ったデータの挿入を引き起こす可能性があります。

(2) UPDATE — データの更新

SQL
-- 特定の行を更新
UPDATE テーブル名
SET カラム1 = 新しい値1, カラム2 = 新しい値2
WHERE 条件;

-- 式を使用した更新
UPDATE employees
SET salary = salary * 1.1
WHERE department_id = 1;
💡 ヒント: UPDATEを実行する前に、SELECTでWHERE条件がどの行にマッチするか確認してください。例えば、まずSELECT * FROM employees WHERE department_id = 1;を実行して、何行が影響を受けるかを確認します。

(3) DELETE — データの削除

SQL
-- 特定の行を削除
DELETE FROM テーブル名
WHERE 条件;

-- すべての行を削除(行ごとに削除、テーブル構造は保持)
DELETE FROM テーブル名;
💡 ヒント: 削除されたデータはトランザクションロールバックで回復可能です(トランザクション内であれば)。ただし、コミット後は回復できません。SELECTしてからDELETEする習慣をつけましょう。

(4) TRUNCATE — テーブルのクリア

SQL
-- テーブル全体をクリア(テーブル構造は保持)
TRUNCATE TABLE テーブル名;
💡 ヒント: SQLiteでのTRUNCATEはDELETE FROM テーブル名と等価です(SQLiteはTRUNCATE構文をサポートしていません)。MySQL/PostgreSQLでは、TRUNCATEはDELETEよりはるかに高速です。行ごとに削除せず、自動採番IDをリセットします。

(5) INSERT vs DELETE vs TRUNCATEの比較

操作 効果 ロールバック可能 自動採番IDリセット 速度
INSERT 新しい行を挿入
DELETE 行ごとに削除(WHERE使用可能) 遅い
TRUNCATE テーブル全体をクリア 速い


3. コード例

(1) サンプル:従業員と部署データの挿入(難易度⭐)

部署テーブルと従業員テーブルに初期データを挿入します。

SQL
-- まず部署データを挿入
INSERT INTO departments (name, location)
VALUES ('Engineering', 'New York'),
       ('Marketing', 'Los Angeles'),
       ('Finance', 'New York');

-- 次に従業員データを挿入
INSERT INTO employees (name, department_id, salary, hire_date)
VALUES ('John', 1, 15000.00, '2023-01-15'),
       ('Jane', 1, 18000.00, '2022-06-01'),
       ('Bob', 2, 12000.00, '2023-03-20'),
       ('Alice', 3, 13000.00, '2021-11-10');

-- 挿入結果を確認
SELECT * FROM departments;
▶ 試してみよう

出力

TEXT 📖 参照専用
id  name         location
--  -----------  ----------
1   Engineering  New York
2   Marketing    Los Angeles
3   Finance      New York

(2) サンプル:従業員給与の安全な更新(難易度⭐⭐)

エンジニアリング部門の全従業員に10%の昇給を与えます。まず確認してから実行します。

SQL
-- ステップ1:SELECTで影響範囲を確認
SELECT name, salary
FROM employees
WHERE department_id = 1;
▶ 試してみよう

更新前

TEXT 📖 参照専用
name    salary
------  --------
John    15000.00
Jane    18000.00
SQL
-- ステップ2:確認後に更新を実行
UPDATE employees
SET salary = salary * 1.1
WHERE department_id = 1;

-- ステップ3:更新結果を確認
SELECT name, salary
FROM employees
WHERE department_id = 1;

更新後

TEXT 📖 参照専用
name    salary
------  --------
John    16500.00
Jane    19800.00

(3) サンプル:削除とクリア操作の比較(難易度⭐⭐⭐)

DELETEとTRUNCATEの動作の違いを比較します。

SQL
-- 一時テストテーブルを作成
CREATE TABLE test_delete (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT
);

-- テストデータを挿入
INSERT INTO test_delete (name) VALUES ('A'), ('B'), ('C');

-- DELETEで特定の行を削除
DELETE FROM test_delete WHERE name = 'B';

SELECT * FROM test_delete;
▶ 試してみよう

出力

TEXT 📖 参照専用
id  name
--  ----
1   A
3   C
SQL
-- DELETEで残りのデータをクリア
DELETE FROM test_delete;

-- 新しいデータを挿入し、自動採番IDを確認
INSERT INTO test_delete (name) VALUES ('D');

SELECT * FROM test_delete;

出力(IDが4から始まっていることに注目。自動採番IDはリセットされていない):

TEXT 📖 参照専用
id  name
--  ----
4   D
💡 MySQLでは、TRUNCATE TABLE test_delete;でテーブルをクリアすると、新しいデータの挿入時にIDが1から再開します。



4. 主な応用シナリオ

(1) シナリオ1:バッチデータインポート

一時テーブルや外部データソースからバッチインポートします:

SQL
-- 高給従業員をバックアップテーブルにコピー
INSERT INTO employees_backup (name, department_id, salary, hire_date)
SELECT name, department_id, salary, hire_date
FROM employees
WHERE salary > 15000;

(2) シナリオ2:条件付きバッチ更新

特定の条件下でデータを調整します:

SQL
-- 入社から3年以上3年以上経過した従業員に5%の昇給
UPDATE employees
SET salary = salary * 1.05
WHERE hire_date < DATE('now', '-3 years');

▶ サンプル

SQL
INSERT INTO users (name, age) VALUES ('田中', 30);
▶ 試してみよう

❓ よくある質問

Q DELETEとTRUNCATEの両方でテーブルをクリアできます。どちらを使うべきですか?
A
Q WHERE条件を忘れてテーブル全体を更新してしまいましたどうすればいいですか?
A
Q INSERT時に特定の列を入力したくない場合はどうすればいいですか?
A
Q SQLiteはTRUNCATEをサポートしていますか?
A

📖 まとめ


📝 練習問題

(1) 演習1(⭐)

以下の商品データをproductsテーブルに挿入し、クエリで確認してください:

name category price stock
iPhone 15 Phone 5999.00 100
MacBook Pro Computer 12999.00 50
AirPods Pro Accessory 1899.00 200
iPad Air Tablet 4799.00 80

(2) 演習2(⭐⭐)

以下の操作を完了してください。各ステップの前にSELECTで確認してください:

  1. 在庫が100未満のすべての商品の価格を5%引き上げ
  2. 「Accessory」カテゴリの商品の在庫を50増加
  3. 価格が2000未満の商品を削除

(3) 演習3(⭐⭐⭐)

「商品の販売停止」プロセスをシミュレート:

  1. 在庫が0の商品をproductsテーブルから新しいproducts_offlineテーブルにコピー(まずテーブルを作成)
  2. productsテーブルからこれらの在庫切れ商品を削除
  3. 両方のテーブルのデータが正しいことを確認


5. 次のレッスン

👉 05-データ型

Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%