Lesson 10
SELECT以外の文
Lesson 10
Chapter 1
本レッスンについて
本レッスンでは、SELECT 文以外の文のうち特に重要な文について学んでいきます。
SQL で使用できる「文(コマンド)」は、以下に説明するように、おおよそ 10 数種類程度となります。
SQL で使用できる文について
ここで SQL で使用できる文(コマンド)の全体像を俯瞰しておきましょう。
SQL で使用できる文には、大きな分類として「DDL(データ定義言語)」と「DML(データ操作言語)」の 2 種類があります。
DDL(データ定義言語:Data Definition Language)とは、テーブルの作成(CREATE)・削除(DROP)やアクセス権限の設定など、データベースのデータ構造を定義する言語となります。
DML(データ操作言語:Data Manipulation Language)とは、既存のテーブルへのデータの追加(INSERT)・変更(UPDATE)・削除(DELETE)・取得(SELECT)など、データベースのデータを操作する言語となります。
SQL で使用できる主な文は下表のとおりです。
分類 | コマンド | 説明 |
---|---|---|
DDL(データ定義言語) | CREATE | テーブル・ビューなどを作成する |
ALTER | テーブル・ビューなどを変更する | |
DROP | テーブル・ビューなどを削除する | |
TRUNCATE | テーブルを再作成する | |
GRANT | アクセス権限を与える | |
REVOKE | アクセス権限を取り消す | |
DML(データ操作言語) | SELECT | テーブルからレコードを取得する |
INSERT | テーブルにレコードを追加する | |
UPDATE | テーブルのレコードを変更する | |
DELETE | テーブルのレコードを削除する |
本レッスンでは、上記の文のうち、プログラム上で多く使用される DML(データ操作言語)を中心として、INSERT 文、UPDATE 文、DELETE 文、TRUNCATE 文について取り上げていきます。
テーブルの準備
本レッスンで使用するテーブルを準備します。
今回も、テーブルを 2 つ作成します。練習も兼ねて、手順どおりに作成を進めてください。
データベースの選択
まず、test データベースを選択します。
PowerShell
mysql> use test;
不要なテーブルを削除する
次に、Lesson 6 で作成した members テーブルを削除します。
以下の SQL を実行してください(IF EXISTS
を付けているので、既にテーブルが存在しなければ空振りとなります)。
PowerShell
mysql> DROP TABLE IF EXISTS members;
テーブルが削除できているか確認してみましょう。
以下の SHOW TABLES
コマンドで、テーブルの一覧を表示します。
PowerShell
mysql> SHOW TABLES;
+----------------+
| Tables_in_test |
+----------------+
| cards |
| employees |
| lists |
| operators |
| prefectures |
| projects |
| sample |
| users |
+----------------+
8 rows in set (0.00 sec)
members テーブルが削除できたことが確認できました。
members テーブルの作成
それでは、次のように本レッスン用の members
テーブルを作成しましょう。
なお、このテーブルには、初期データは入れません。
PowerShell
mysql> CREATE TABLE members (
id int PRIMARY KEY AUTO_INCREMENT,
name varchar(20),
age tinyint,
prefecture varchar(20),
attendance boolean DEFAULT true
);
作成したテーブルの内容は SHOW CREATE TABLE 文で確認できます。
SHOW CREATE TABLE members\G
とコマンドを打って、確認してみましょう。
PowerShell
mysql> SHOW CREATE TABLE members\G
*************************** 1. row ***************************
Table: members
Create Table: CREATE TABLE `members` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
`age` tinyint(4) DEFAULT NULL,
`prefecture` varchar(20) DEFAULT NULL,
`attendance` tinyint(1) DEFAULT '1',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
1 row in set (0.00 sec)
AUTO_INCREMENT 属性と DEFAULT 制約
テーブルの作成において、AUTO_INCREMENT と DEFAULT という語句が出てきていますので、簡単に補足します。
① AUTO_INCREMENT 属性
AUTO_INCREMENT 属性を使用すると、自動的に連番が生成されます。必ず一意の値(ユニーク値)となり他と重複しません。
指定方法は、次のとおりです。
[カラム名] [データ型] AUTO_INCREMENT
② DEFAULT 制約
DEFAULT 制約を使用すると、値の指定が無い場合は、デフォルト値を格納します。
指定方法は、次のとおりです。
[カラム名] [データ型] DEFAULT [デフォルト値]
new_members テーブルの作成
続いて、new_members
テーブルを作成します。
次のように、CREATE TABLE 文、INSERT 文のコマンドを実行してください。
PowerShell
mysql> CREATE TABLE new_members (
id int PRIMARY KEY,
name varchar(20),
age tinyint,
gender varchar(8),
prefecture varchar(20)
);
mysql> INSERT INTO new_members VALUES
(1, 'watanabe', 25, 'male', 'tokyo'),
(2, 'yamamoto', 41, 'female', 'tokyo'),
(3, 'kato', 68, 'female', 'fukuoka');
mysql> SELECT * FROM new_members;
+----+----------+------+--------+------------+
| id | name | age | gender | prefecture |
+----+----------+------+--------+------------+
| 1 | watanabe | 25 | male | tokyo |
| 2 | yamamoto | 41 | female | tokyo |
| 3 | kato | 68 | female | fukuoka |
+----+----------+------+--------+------------+
3 rows in set (0.00 sec)
以上のように、ID(id)、名前(name)、年齢(age)、性別(gender)、都道府県ID(prefecture_id)をカラムに持った表ができていれば OK です。

Lesson 10
Chapter 2
INSERT文
INSERT 文は、テーブルに新しいレコードを追加するときに使用します。
これまでのレッスンでも、折々に触れてきましたので、おおよその機能はイメージできていることと思います。
この Chapter では、これまでの復習を行いながら、もう少し踏み込んだ内容を学んでいきます。
レコードを 1 件追加する
① 全てのカラムを指定してデータを登録する
INSERT 文の基本構文は次のとおりです。
INSERT INTO [テーブル名] (カラム名1, カラム名2, ...) VALUES (値1, 値2, ...);
早速、members テーブルに新しいデータを追加してみましょう。
まず、次のように、基本に忠実に INSERT INTO 文を実行してください。
PowerShell
mysql> INSERT INTO members (id, name, age, prefecture, attendance) VALUES
(1, 'tanaka', 28, 'tokyo', true);
データが挿入できたか、SELECT 文で確認してみましょう。
PowerShell
mysql> SELECT * FROM members;
+----+--------+------+------------+------------+
| id | name | age | prefecture | attendance |
+----+--------+------+------------+------------+
| 1 | tanaka | 28 | tokyo | 1 |
+----+--------+------+------------+------------+
1 row in set (0.00 sec)
以上のように表示されれば OK です。
② カラム名の指定を省略する
CERATE TABLE 文で定義された順に全てのカラムの値を指定する場合は、以下のようにカラム名の指定を省略することができます。
INSERT INTO [テーブル名] VALUES (値1, 値2, ...);
それでは、カラム名の指定を省略して、members テーブルにデータを追加してみましょう。
次のように、INSERT INTO 文を実行してください。
PowerShell
mysql> INSERT INTO members VALUES (2, 'yamada', 19, 'osaka', true);
データが挿入できたか、SELECT 文で確認してみましょう。
PowerShell
mysql> SELECT * FROM members;
+----+--------+------+------------+------------+
| id | name | age | prefecture | attendance |
+----+--------+------+------------+------------+
| 1 | tanaka | 28 | tokyo | 1 |
| 2 | yamada | 19 | osaka | 1 |
+----+--------+------+------------+------------+
2 rows in set (0.00 sec)
間違いがなければ、以上のように追加されます。
③ データの一部を指定する
AUTO_INCREMENT 属性や DEFAULT 制約があるカラムは、INSERT INTO 文に指定しなくとも、自動的にデータが登録されます。
では、name
, age
, prefecture
の値のみを指定して INSERT INTO 文を実行してみましょう。
PowerShell
mysql> INSERT INTO members (name, age, prefecture) VALUES ('suzuki', 33, 'tokyo');
SELECT 文で確認してみましょう。
PowerShell
mysql> SELECT * FROM members;
+----+--------+------+------------+------------+
| id | name | age | prefecture | attendance |
+----+--------+------+------------+------------+
| 1 | tanaka | 28 | tokyo | 1 |
| 2 | yamada | 19 | osaka | 1 |
| 3 | suzuki | 33 | tokyo | 1 |
+----+--------+------+------------+------------+
3 rows in set (0.00 sec)
AUTO_INCREMENT により id に 3
が自動で採番され、attendance にはデフォルト値の 1(true)
が登録されています。
複数のレコードを同時に追加する(バルクインサート)
INSERT INTO 文で複数のレコードを同時に追加することができます。
次のように VALUE 以下にカンマ区切りで複数のデータを追加します。
INSERT INTO [テーブル名] (カラム名1, カラム名2, ...)
VALUES (値1, 値2, ...), (値1, 値2, ...), (値1, 値2, ...);
この方法は、一般的に「バルクインサート」と呼ばれていて、SQL 文の実行にかかる処理のオーバーヘッドが 1 回分で済むことから高速となります。
それでは次のようにバルクインサートを使用して INSERT INTO 文を実行してみましょう。
PowerShell
mysql> INSERT INTO members (name, age, prefecture) VALUES
('saito', 48, 'nagoya'),
('honda', 31, 'osaka'),
('nakamura', 23, 'tokyo');
SELECT 文で確認してみましょう。
PowerShell
mysql> SELECT * FROM members;
+----+----------+------+------------+------------+
| id | name | age | prefecture | attendance |
+----+----------+------+------------+------------+
| 1 | tanaka | 28 | tokyo | 1 |
| 2 | yamada | 19 | osaka | 1 |
| 3 | suzuki | 33 | tokyo | 1 |
| 4 | saito | 48 | nagoya | 1 |
| 5 | honda | 31 | osaka | 1 |
| 6 | nakamura | 23 | tokyo | 1 |
+----+----------+------+------------+------------+
6 rows in set (0.00 sec)
正しく 3 つのデータが追加されました。
他のテーブルからデータを追加する(INSERT ... SELECT 文)
INSERT ... SELECT 構文を使用することで、他のテーブルからデータを取得して追加をすることができます。
構文は次のとおりです。
INSERT INTO [テーブル名] (カラム名1, カラム名2, ...)
SELECT カラムA, カラムB, ... FROM [他のテーブル名] WHERE [抽出条件];
具体例を見た方が分かりやすいです。SQL 文は次のようになります。
PowerShell
mysql> INSERT INTO members (name, age, prefecture)
SELECT name, age, prefecture FROM new_members;
上記 SQL の SELECT 以下は、今まで学んできた SELECT 文と同じ構造です。
必要に応じて WHERE 句など、自由に使うことができます。
上記の INSERT ... SELECT 文を実行したら、テーブルの中身を確認してみましょう。
PowerShell
mysql> SELECT * FROM members;
+----+----------+------+------------+------------+
| id | name | age | prefecture | attendance |
+----+----------+------+------------+------------+
| 1 | tanaka | 28 | tokyo | 1 |
| 2 | yamada | 19 | osaka | 1 |
| 3 | suzuki | 33 | tokyo | 1 |
| 4 | saito | 48 | nagoya | 1 |
| 5 | honda | 31 | osaka | 1 |
| 6 | nakamura | 23 | tokyo | 1 |
| 7 | watanabe | 25 | tokyo | 1 |
| 8 | yamamoto | 41 | tokyo | 1 |
| 9 | kato | 68 | fukuoka | 1 |
+----+----------+------+------------+------------+
9 rows in set (0.00 sec)
new_members テーブルのデータが正しく追加されたことが確認できます。

Lesson 10
Chapter 3
UPDATE文
この Chapter では、前の Chapter で INSERT した以下の members テーブルをそのまま使用します。
+----+----------+------+------------+------------+
| id | name | age | prefecture | attendance |
+----+----------+------+------------+------------+
| 1 | tanaka | 28 | tokyo | 1 |
| 2 | yamada | 19 | osaka | 1 |
| 3 | suzuki | 33 | tokyo | 1 |
| 4 | saito | 48 | nagoya | 1 |
| 5 | honda | 31 | osaka | 1 |
| 6 | nakamura | 23 | tokyo | 1 |
| 7 | watanabe | 25 | tokyo | 1 |
| 8 | yamamoto | 41 | tokyo | 1 |
| 9 | kato | 68 | fukuoka | 1 |
+----+----------+------+------------+------------+
基本的構文
UPDATE文は、テーブルに登録されているレコードを更新するときに使用します。
UPDATE 文の基本構文は次のとおりです。
UPDATE [テーブル名] SET [カラム名1] = [値1], [カラム名2] = [値2], ... WHERE [抽出条件];
1 つのカラムを更新する
members テーブルの id = 1
のレコードにつき、prefecture を tokyo から osaka に更新してみましょう。
SQL 文は次のように記述します。
PowerShell
UPDATE members SET prefecture = 'osaka' WHERE id = 1;
SQL を実行して、データが更新できたか、SELECT 文で確認してみましょう。
PowerShell
mysql> SELECT * FROM members;
+----+----------+------+------------+------------+
| id | name | age | prefecture | attendance |
+----+----------+------+------------+------------+
| 1 | tanaka | 28 | osaka | 1 |
| 2 | yamada | 19 | osaka | 1 |
| 3 | suzuki | 33 | tokyo | 1 |
| 4 | saito | 48 | nagoya | 1 |
| 5 | honda | 31 | osaka | 1 |
| 6 | nakamura | 23 | tokyo | 1 |
| 7 | watanabe | 25 | tokyo | 1 |
| 8 | yamamoto | 41 | tokyo | 1 |
| 9 | kato | 68 | fukuoka | 1 |
+----+----------+------+------------+------------+
9 rows in set (0.00 sec)
id = 1 のレコードにつき、prefecture が osaka と変更されていることが確認できました。
複数のカラムを更新する
次に、複数のカラムを更新してみましょう。
members テーブルの id = 2
のレコードにつき、age を 20 に、prefecture を osaka から tokyo に更新するようにします。
複数のカラム更新の指定は、SET 句以下にカンマで区切って記述します。
次のように SQL 文を記述して実行してみましょう。
PowerShell
mysql> UPDATE members SET age = 20, prefecture = 'tokyo' WHERE id = 2;
Query OK, 1 row affected (0.02 sec)
Rows matched: 1 Changed: 1 Warnings: 0
SELECT 文で確認してみましょう。
PowerShell
mysql> SELECT * FROM members;
+----+----------+------+------------+------------+
| id | name | age | prefecture | attendance |
+----+----------+------+------------+------------+
| 1 | tanaka | 28 | osaka | 1 |
| 2 | yamada | 20 | tokyo | 1 |
| 3 | suzuki | 33 | tokyo | 1 |
| 4 | saito | 48 | nagoya | 1 |
| 5 | honda | 31 | osaka | 1 |
| 6 | nakamura | 23 | tokyo | 1 |
| 7 | watanabe | 25 | tokyo | 1 |
| 8 | yamamoto | 41 | tokyo | 1 |
| 9 | kato | 68 | fukuoka | 1 |
+----+----------+------+------------+------------+
9 rows in set (0.00 sec)
age と prefecture の 2 つのカラムが変更されていることが確認できました。
複数のレコードを更新する
UPDATE 文は、指定された条件に合うレコードを全て更新します。
members テーブルの prefecture = 'tokyo'
のレコード全てにつき、attendance を 0 (false)
に更新するようにします。
次のように SQL 文を記述して実行してみましょう。
PowerShell
mysql> UPDATE members SET attendance = false WHERE prefecture = 'tokyo';
Query OK, 5 rows affected (0.02 sec)
Rows matched: 5 Changed: 5 Warnings: 0
更新結果を SELECT 文で確認してみましょう。
PowerShell
mysql> SELECT * FROM members;
+----+----------+------+------------+------------+
| id | name | age | prefecture | attendance |
+----+----------+------+------------+------------+
| 1 | tanaka | 28 | osaka | 1 |
| 2 | yamada | 20 | tokyo | 0 |
| 3 | suzuki | 33 | tokyo | 0 |
| 4 | saito | 48 | nagoya | 1 |
| 5 | honda | 31 | osaka | 1 |
| 6 | nakamura | 23 | tokyo | 0 |
| 7 | watanabe | 25 | tokyo | 0 |
| 8 | yamamoto | 41 | tokyo | 0 |
| 9 | kato | 68 | fukuoka | 1 |
+----+----------+------+------------+------------+
9 rows in set (0.00 sec)
prefecture = 'tokyo'
のレコードについて、attendance が 0 (false)
に変更されていることが確認できました。

Lesson 10
Chapter 4
DELETE文
この Chapter では、前の Chapter で使用した以下の members テーブルをそのまま使用します。
+----+----------+------+------------+------------+
| id | name | age | prefecture | attendance |
+----+----------+------+------------+------------+
| 1 | tanaka | 28 | osaka | 1 |
| 2 | yamada | 20 | tokyo | 0 |
| 3 | suzuki | 33 | tokyo | 0 |
| 4 | saito | 48 | nagoya | 1 |
| 5 | honda | 31 | osaka | 1 |
| 6 | nakamura | 23 | tokyo | 0 |
| 7 | watanabe | 25 | tokyo | 0 |
| 8 | yamamoto | 41 | tokyo | 0 |
| 9 | kato | 68 | fukuoka | 1 |
+----+----------+------+------------+------------+
基本的構文
DELETE文は、テーブルに登録されているレコードを削除するときに使用します。
DELETE 文の基本構文は次のとおりです。
DELETE FROM [テーブル名] WHERE [抽出条件];
条件指定したデータを削除する
members テーブルの id = 3
のレコードを削除してみましょう。
SQL 文は次のように記述します。
PowerShell
DELETE FROM members WHERE id = 3;
SQL を実行して、データが削除できたか、SELECT 文で確認してみましょう。
PowerShell
mysql> SELECT * FROM members;
+----+----------+------+------------+------------+
| id | name | age | prefecture | attendance |
+----+----------+------+------------+------------+
| 1 | tanaka | 28 | osaka | 1 |
| 2 | yamada | 20 | tokyo | 0 |
| 4 | saito | 48 | nagoya | 1 |
| 5 | honda | 31 | osaka | 1 |
| 6 | nakamura | 23 | tokyo | 0 |
| 7 | watanabe | 25 | tokyo | 0 |
| 8 | yamamoto | 41 | tokyo | 0 |
| 9 | kato | 68 | fukuoka | 1 |
+----+----------+------+------------+------------+
8 rows in set (0.00 sec)
id = 3 のレコードにつき、レコードが削除されていることが確認できました。
全てのデータを削除する
続いて members テーブルの全てのレコードを削除してみましょう。
この場合、抽出条件の WHERE 句は使用せず DELETE FROM [テーブル名]
という形式で SQL 文を記述します。
それでは、次のように SQL 文を実行しましょう。
PowerShell
mysql> DELETE FROM members;
Query OK, 8 rows affected (0.00 sec)
以下のように、SELECT 文で実行結果を確認してみましょう。
PowerShell
mysql> SELECT * FROM members;
Empty set (0.00 sec)
テーブルの取得結果として Empty set
と返却されました。
これは、テーブルのレコードが 0 件という状態を表します。
したがって、DELETE 文が正常に実行され、全てのレコードが削除されたということになります。
DELETE 文を実行した際の AUTO_INCREMENT の挙動について
ここで、1 つ確認をしておきます。
DELETE 文で全てのレコードを削除した後に、新しいレコードを追加した場合、AUTO_INCREMENT
による id の採番はどのようになるかということです。
次のように INSERT 文を使用して、SQL を実行してみてください。
PowerShell
mysql> INSERT INTO members (name, age, prefecture) VALUES
('tanaka', 28, 'tokyo'),
('yamada', 19, 'osaka'),
('suzuki', 33, 'tokyo');
データ追加後のテーブルを確認してみると、次のようになっています。
PowerShell
mysql> SELECT * FROM members;
+----+--------+------+------------+------------+
| id | name | age | prefecture | attendance |
+----+--------+------+------------+------------+
| 10 | tanaka | 28 | tokyo | 1 |
| 11 | yamada | 19 | osaka | 1 |
| 12 | suzuki | 33 | tokyo | 1 |
+----+--------+------+------------+------------+
3 rows in set (0.00 sec)
削除前の最終レコードの id = 9 の続きとして、新しいレコードの id は 10 から採番されることが確認できました。
これは、DELETE 文には、削除したレコードの記録を保持する仕組みがあるためです。この仕組みから、削除処理の取消し(ロールバック)などの実装をすることが可能となっています。
この結果については、次に紹介する TRUNCATE 文において、また言及します。

Lesson 10
Chapter 5
TRUNCATE文
ここでは、前の Chapter で使用したテーブルをそのまま使用して説明をしていきます。
+----+--------+------+------------+------------+
| id | name | age | prefecture | attendance |
+----+--------+------+------------+------------+
| 10 | tanaka | 28 | tokyo | 1 |
| 11 | yamada | 19 | osaka | 1 |
| 12 | suzuki | 33 | tokyo | 1 |
+----+--------+------+------------+------------+
基本的構文
TRUNCATE 文は、テーブルに登録されているレコードを全て削除するときに使用します。
基本構文は次のとおりです。
TRUNCATE [テーブル名];
レコードを全削除するという点では、前の Chapter で学んだ DELETE FROM [テーブル名]
構文と同じ機能ということができます。
TRUNCATE 文と DELETE 文の違い
では、TRUNCATE 文と DELETE 文の違いはどこにあるのでしょうか。
大きな違いは、DELETE 文では「テーブルを保持したまま削除している」のに対して、TRUNCATE 文では「テーブルを削除して再作成している」という点にあります。
DELETE 文と TRUNCATE 文の比較
項目 | DELETE 文 | TRUNCATE 文 |
---|---|---|
処理内容 | テーブルを保持したままレコードを削除する | テーブルを削除して再作成する |
削除対象 | 削除するレコードを選択できる | 全件削除のみ |
削除記録 | 削除したレコードの記録を保持するためロールバックの実装が可能 | 削除記録は残らない |
AUTO_INCREMENT | AUTO_INCREMENT は削除されない | AUTO_INCREMENT は削除されるので 1 番から採番される |
処理速度 | 一定程度の時間がかかる | 高速 |
分類 | DML(データ操作言語) | DDL(データ定義言語) |
TRUNCATE 文は、テーブルを削除して再作成するため、高速でデータを削除することができますが、削除記録などが残らないため、状況に応じて DELETE 文と使い分けるようにしましょう。
データ削除の実行
それでは TRUNCATE 文を使用して members テーブルのレコードを削除してみましょう。
次のように SQL 文を実行してください。
PowerShell
mysql> TRUNCATE members;
Query OK, 0 rows affected (0.05 sec)
SELECT 文で実行結果を確認してみましょう。
PowerShell
mysql> SELECT * FROM members;
Empty set (0.00 sec)
テーブルの取得結果として Empty set
と返却されました。
TRUNCATE 文で、全てのレコードが削除されたことが確認できました。
TRUNCATE 文を実行した際の AUTO_INCREMENT の挙動について
TRUNCATE 文で、AUTO_INCREMENT がどのように採番されるか確認してみましょう。
次のように INSERT 文を使用して、SQL を実行してみてください。
PowerShell
mysql> INSERT INTO members (name, age, prefecture) VALUES
('tanaka', 28, 'tokyo'),
('yamada', 19, 'osaka'),
('suzuki', 33, 'tokyo');
データ追加後のテーブルを確認してみると、次のようになりました。
PowerShell
mysql> SELECT * FROM members;
+----+--------+------+------------+------------+
| id | name | age | prefecture | attendance |
+----+--------+------+------------+------------+
| 1 | tanaka | 28 | tokyo | 1 |
| 2 | yamada | 19 | osaka | 1 |
| 3 | suzuki | 33 | tokyo | 1 |
+----+--------+------+------------+------------+
3 rows in set (0.00 sec)
id が 1 から採番されていますね。
こういったところも DELETE 文と挙動が変わってきます。
TRUNCATE 文の性質を把握した上で、必要に応じて適切に使用できるようにしましょう。
本レッスンは、以上です。
