0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SQL超入門:基本文法をオンライン実行環境で確認する

0
Last updated at Posted at 2025-10-16

はじめに

 SQLの基本をまとめています。記事は随時更新予定です。

準備

SQLとは何か

 SQL(Structured Query Language、構造化問い合わせ言語)とは、RDBMS(Relational Database Management System、関係データベース管理システム)によってRDB(Relational Database、関係データベース)内のデータを操作・管理するために使用される標準的な言語です[1]。

SQLは厳密にはプログラミング言語ではありません。アプリケーション内では、ほかのプログラミング言語と併用して使用されます。

データベースとは何か

 データベースとは、電子的に保存され、アクセスできる組織化されたデータの集合です[2]。「組織化されたデータの集合」と言うと複雑そうですが、要するにデータ集合が何らかのルールに従っているというような認識で大まかにはよいと思います。そのルール次第で様々なデータベースが存在します。

関係データベースとは何か

 データベースの中でも特によく用いられるのが関係データベースです。関係データベースは表形式のデータ構造をもつ複数のテーブルとそれらの関係によって構造化されます。テーブルの最も簡単なイメージはExcelの表です。テーブルには横の行(レコード)と縦の列(カラム)があります。

関係データベース管理システム(RDBMS)とは何か

 関係データベースはRDBMSによって管理されます。主要なRDBMSにはOracle DatabaseMicrosoft SQL ServerMySQLPostgreSQLなどがあります。Microsoft SQL ServerはMicrosoftとの高い互換性で有名です。MySQLは根強い人気がありますが、近年はOSSのPostgreSQLがMySQLに追いつく勢いで人気を高めています。

SQLの分類

 SQL文は、三種類に大別できます。

  1. DDL(data definition language、データ定義言語)
    • CREATE:データベースオブジェクトの定義
    • ALTER:データベースオブジェクトの定義変更
    • DROP:データベースオブジェクトの削除

データ定義言語はテーブルを作成したり、構造を変更したり、削除したりするためのSQLです。テーブルだけでなく、データベースそのものや、ビュー、ストアドプロシージャなどのデータベースオブジェクトも作成・変更・削除することができます。

  1. DML(data manipulation language、データ操作言語)
    • SELECT:データベースのデータを取得
    • INSERT:データベースにデータを追加
    • UPDATE:データベースに保存されているデータを更新
    • DELETE:データベースに保存されているデータを削除

データ操作言語はデータベースのデータを自由に操作するための基本的な文法です。

  1. DCL(data control language、データ制御言語)
    • BEGIN:トランザクションを開始
    • COMMIT:トランザクションを確定
    • ROLLBACK:トランザクションを取り消し

データ制御言語は、トランザクションを制御するためのSQLです。トランザクションとは、複数のSQL文をひとまとまりのデータ処理として扱うための仕組みです。このようにSQL文をまとめて扱うことで処理が部分的に失敗してデータの整合性や一貫性が失われることを防ぐことができます。
 トランザクションはACID特性、つまり原子性(Atomicity)、一貫性(Consistency)、独立性(Isolation)、永続性(Durability)を持つべきものとして考えられています。

SQLの命名規則

 SQLは原則として大文字と小文字を区別しません。したがって、変数名の重複には注意する必要があります。
 細かい命名規則はプロジェクトや使用するRDBMSによって少しづつ変わると思います。しかし、複合語を使うときはキャメルケース(UserNameuserName)やケバブケース(user-name)ではなくスネークケース(USER_NAMEuser_name)にし、大文字か小文字に統一するのが一般的です。
 また、明確な決まりはありませんが、慣習として、キーワードを大文字、テーブル名やカラム名を小文字に統一することがあります。以降はそのスタイルで記述します。

実行環境

 本記事では実行環境にpaizaのオンライン・実行環境を使用します。こちらのページに進み、左上の緑の言語選択ボタンからMySQLを選択すれば準備完了です。登録は必要ありません。すでにRDBMSをお使いの方は普段の環境で大丈夫です。

 SQLはRDBMSの扱い、ひいては環境設定と切っても切り離せないと思います。しかし、本記事の目的はSQLの最も基本的な文法をまとめることにありますし、RDBMSの説明は手に余ると感じています。そこで、あえてここでは環境については詳しく書きません。

レベル1

テーブルの作成:CREATE TABLE

 CREATE TABLEで新しいテーブルを作成します。

CREATE TABLE employee (
    id INT PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    furigana VARCHAR(50) NOT NULL,
    gender CHAR(1) NOT NULL CHECK (gender IN ('F', 'M')),
    birth_date DATE NOT NULL
);

 ここでは5つのカラム名(idnamefuriganagenderbirth_date)とカラムに格納されるべきデータの種類が定義されています。例えばfuriganaには50文字以下の可変長文字列(VARCHAR(50))であって、かつNULLでない(NOT NULL)のデータが格納されます。それ以外のデータを格納しようとするとはじかれてしまいます。
 また、SQLの重要な概念として主キー(PRIMARY KEY)というものがあります。これはSQLのレコードを管理するために使われる最も重要な通し番号です。ここではidPRIMARY KEYとして定義されています。

データの追加:INSERT INTO

 作成したテーブルにデータを挿入します。

CREATE TABLE employee (
    id INT PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    furigana VARCHAR(50) NOT NULL,
    gender CHAR(1) NOT NULL CHECK (gender IN ('F', 'M')),
    birth_date DATE NOT NULL
);

INSERT INTO employee (id, name, furigana, gender, birth_date) VALUES
(2, 'Hanako Sato', 'サトウ ハナコ', 'F', '1988-10-15'),
(1, 'Taro Tanaka', 'タナカ タロウ', 'M', '1985-04-01'),
(4, 'Mari Takahashi', 'タカハシ マリ', 'F', '1990-01-05'),
(3, 'Ichiro Suzuki', 'スズキ イチロウ', 'M', '1992-06-20');

データの取得:SELECT~FROM

 テーブルのすべてのデータを取得するにはワイルドカード*を使用してこのように記述します。

CREATE TABLE employee (
    id INT PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    furigana VARCHAR(50) NOT NULL,
    gender CHAR(1) NOT NULL CHECK (gender IN ('F', 'M')),
    birth_date DATE NOT NULL
);

INSERT INTO employee (id, name, furigana, gender, birth_date) VALUES
(2, 'Hanako Sato', 'サトウ ハナコ', 'F', '1988-10-15'),
(1, 'Taro Tanaka', 'タナカ タロウ', 'M', '1985-04-01'),
(4, 'Mari Takahashi', 'タカハシ マリ', 'F', '1990-01-05'),
(3, 'Ichiro Suzuki', 'スズキ イチロウ', 'M', '1992-06-20');

SELECT * FROM employee;
id name furigana gender birth_date
2 Hanako Sato サトウ ハナコ F 1988-10-15
1 Taro Tanaka タナカ タロウ M 1985-04-01
4 Mari Takahashi タカハシ マリ F 1990-01-05
3 Ichiro Suzuki スズキ イチロウ M 1992-06-20

 以降、CREATEINSERT INTOは省略します。SELECTではカラムを指定してidnameだけを出力することもできます。

SELECT id, name FROM employee;
id name
2 Hanako Sato
1 Taro Tanaka
4 Mari Takahashi
3 Ichiro Suzuki

条件の指定:WHERE

条件を指定して表示することもできます。

SELECT * FROM employee
WHERE gender = 'F';
id name furigana gender birth_date
2 Hanako Sato サトウ ハナコ F 1988-10-15
4 Mari Takahashi タカハシ マリ F 1990-01-05

データのソート:ORDER BY

 先ほどまでのデータはidが昇順となっていませんでした。ORDER BY句を使えばデータをキーの値でソートして出力することもできます。

SELECT * FROM employee
ORDER BY id;
id name furigana gender birth_date
1 Taro Tanaka タナカ タロウ M 1985-04-01
2 Hanako Sato サトウ ハナコ F 1988-10-15
3 Ichiro Suzuki スズキ イチロウ M 1992-06-20
4 Mari Takahashi タカハシ マリ F 1990-01-05

誕生日順にすることもできます。

SELECT * FROM employee
ORDER BY birth_date;
id name furigana gender birth_date
1 Taro Tanaka タナカ タロウ M 1985-04-01
2 Hanako Sato サトウ ハナコ F 1988-10-15
4 Mari Takahashi タカハシ マリ F 1990-01-05
3 Ichiro Suzuki スズキ イチロウ M 1992-06-20

データの更新:UPDATE

 サトウさんをサイトウさんに更新してみましょう。

UPDATE employee
SET name = 'Hanako Saito', furigana = 'サイトウ ハナコ'
WHERE id = 2;

SELECT * FROM employee
ORDER BY id;
id name furigana gender birth_date
1 Taro Tanaka タナカ タロウ M 1985-04-01
2 Hanako Saito サイトウ ハナコ F 1988-10-15
3 Ichiro Suzuki スズキ イチロウ M 1992-06-20
4 Mari Takahashi タカハシ マリ F 1990-01-05

データの削除:DELETE

 サトウさんのデータを消してみましょう。

DELETE FROM employee WHERE id = 2;

SELECT * FROM employee
ORDER BY id;
id name furigana gender birth_date
1 Taro Tanaka タナカ タロウ M 1985-04-01
3 Ichiro Suzuki スズキ イチロウ M 1992-06-20
4 Mari Takahashi タカハシ マリ F 1990-01-05

レベル2

テーブルの結合①:INNER JOINJOIN

 関係データベースでは複数のテーブルを使うことがあります。ここでは、社員テーブルと部門テーブルを例に解説します。

  • 社員テーブル
CREATE TABLE employee (
    id INT PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    furigana VARCHAR(50) NOT NULL,
    gender CHAR(1) NOT NULL CHECK (gender IN ('F', 'M')),
    birth_date DATE NOT NULL,
    dep_id INT NOT NULL
);

INSERT INTO employee (id, name, furigana, gender, birth_date,dep_id) VALUES
(1, 'Taro Tanaka', 'タナカ タロウ', 'M', '1985-04-01',1),
(2, 'Hanako Sato', 'サトウ ハナコ', 'F', '1988-10-15',1),
(3, 'Ichiro Suzuki', 'スズキ イチロウ', 'M', '1992-06-20',2),
(4, 'Mari Takahashi', 'タカハシ マリ', 'F', '1990-01-05',2),
(5, 'Kou Ishida', 'イシダ コウ', 'M', '1995-03-11',4);
  • 部門テーブル
CREATE TABLE department (
  dep_id INT PRIMARY KEY,
  dep_name VARCHAR(50) NOT NULL
);

INSERT department (dep_id, dep_name) VALUES
(1, '人事部'),
(2, '営業部'),
(3, '開発部');

この二つのテーブルには共通するカラムdep_idがあります。これをもとにテーブルを結合するには下のようにします。

SELECT employee.id, employee.name, department.dep_id,department.dep_name
FROM employee
INNER JOIN department
ON employee.dep_id = department.dep_id;

同じ意味で下に書くこともできます。employeeedepartmentdという別名(alias)をそれぞれ付けています。Pythonでいうところのimport numpy as npのようなイメージかもしれません。SQLではasのような分かりやすい別名の目印がないので注意が必要です。

SELECT e.id, e.name, d.dep_id,d.dep_name
FROM employee e
INNER JOIN department d
ON e.dep_id = d.dep_id;

ちなみに、INNER JOINは省略して単にJOINと書いても同じ意味になります。

id name dep_id dep_name
1 Taro Tanaka 1 人事部
2 Hanako Sato 1 人事部
3 Ichiro Suzuki 2 営業部
4 Mari Takahashi 2 営業部

ここで注意すべきなのは、departmentのほうでは存在する開発部がINNER JOINの後に消えているという点と、employeeには存在するイシダさんのレコードが消滅しているという点です。INNER JOINは結合部が両方のテーブルにあるものだけを抽出します。
 イシダさんのdep_id4ですが、departmentではdep_id123しかありません。また、開発部のdep_id3ですが、employeeテーブルの中にはdep_id3であるような人はいません。そのような、いわば不完全なデータはINNER JOINでは除外されてしまいます。

テーブルの結合②:LEFT JOINLEFT OUTER JOIN

 LEFT JOINは、左側のテーブルの全てのレコードを取得し、右側のテーブルで結合条件を満たすレコードが存在すればそのデータを結合します。右側に一致するデータがない場合、右側のカラムはNULLになります。
 INNER JOINのコードのSELECT以下の部分を次のように書き換えると違いが分かります。

SELECT employee.id, employee.name, department.dep_id,department.dep_name
FROM employee
LEFT JOIN department
ON employee.dep_id = department.dep_id;

実行結果は以下のようになり、departmentには対応するdep_idを持たないイシダさんのデータが表示されるようになりました。

id name dep_id dep_name
1 Taro Tanaka 1 人事部
2 Hanako Sato 1 人事部
3 Ichiro Suzuki 2 営業部
4 Mari Takahashi 2 営業部
5 Kou Ishida NULL NULL

テーブルの結合③:RIGHT JOINRIGHT OUTER JOIN

 RIGHT JOINLEFT JOINのちょうど逆で、右側のテーブルの全てのレコードを取得し、左側のテーブルで結合条件を満たすレコードが存在すればそのデータを結合します。

SELECT employee.id, employee.name, department.dep_id,department.dep_name
FROM employee
RIGHT JOIN department
ON employee.dep_id = department.dep_id;

実行結果は以下のようになります。

id name dep_id dep_name
1 Taro Tanaka 1 人事部
2 Hanako Sato 1 人事部
3 Ichiro Suzuki 2 営業部
4 Mari Takahashi 2 営業部
NULL NULL 3 開発部
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?