【SQL】データを操る！初心者向けSQL入門講座

# はじめに
こんにちは、エンジニア3年目の嶋田です。
まずは、この記事を開いていただきありがとうございます！

最近、開発中にデータがどのように扱われているか、その構造を理解することがいかに重要かを実感しました…。
特に、どんなデータがどのように保存されているかを把握しながらコーディングすると、ずっと効率的に問題を解決できます。
この記事を通じて、SQLの基本を一緒に学んでいきましょう！

# 目次
- [SQLとは何か](#sqlとは何か)
- [データベースの基礎](#データベースの基礎)
- [SELECTクエリの基本](#selectクエリの基本)
- [データの挿入、更新、削除](#データの挿入、更新、削除)
- [JOINによるテーブルの結合](#joinによるテーブルの結合)
- [集約関数とグループ化](#集約関数とグループ化)
- [最後に](#最後に)
- [参考文献](#参考文献)

# SQLとは何か

SQL（Structured Query Language）は、リレーショナルデータベース管理システム（RDBMS）でデータを操作するために使用される標準的なプログラミング言語です。データベースは情報を整理し保存するシステムであり、SQLはその情報に対して様々な操作を行うための強力なツールです。

## SQLの主な機能
- **データの検索**
    - `SELECT`クエリを使用して、データベースから必要な情報を抽出
- **データの挿入**
    - `INSERT`ステートメントで新しいデータをデータベースに追加
- **データの更新**
    - `UPDATE`ステートメントでデータベースの既存の情報を修正
- **データの削除**
    - `DELETE`ステートメントで不要なデータを削除
- **データベースの管理**
    - データベースの構造を管理するためのコマンドも含まれています。

## SQL環境のセットアップ
SQLを効果的に使用するためには、リレーショナルデータベースのセットアップが必要です。ここでは、WindowsとmacOSでの一般的なSQL環境の設定手順を説明します。

### Windowsでのセットアップ
1. **MySQLのダウンロード**: [MySQL公式サイト](https://dev.mysql.com/downloads/mysql/)からMySQL Community Serverをダウンロードし、インストールします。
2. **MySQL Workbenchのインストール**: [MySQL Workbench](https://dev.mysql.com/downloads/workbench/)をダウンロードし、インストールします。これは、データベースを視覚的に操作しSQLクエリを実行するためのツールです。

### macOSでのセットアップ
1. **Homebrewのインストール**: ターミナルで以下のコマンドを実行し、Homebrewをインストールします。
    ```bash
    /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
    ```
2. **MySQLのインストール**: Homebrewを使用してMySQLをインストールします。
    ```bash
    brew install mysql
    ```
3. **MySQLの起動**: インストール後、以下のコマンドでMySQLサーバーを起動します。
    ```bash
    brew services start mysql
    ```
4. **セキュリティ設定の実施**: 安全性を高めるため、初期設定を行います。
    ```bash
    mysql_secure_installation
    ```
5. **MySQL Workbenchのインストール**: [MySQL Workbench](https://dev.mysql.com/downloads/workbench/)をダウンロードし、インストールします。

# データベースの基本

このセクションでは、データベースの概念、テーブルの作成、およびスキーマの定義について詳しく学びます。リレーショナルデータベースを使用する際には、これらの基本的な概念を理解しておくことが非常に重要です。

## データベースとは

データベースは、関連性のあるデータの集まりを効率的に管理、格納、検索するためのシステムです。データベースを使用することで、大量のデータを簡単かつ安全に扱うことができます。

## データベースの作成

SQLを使用して新しいデータベースを作成するには、以下のようなコマンドを使用します。

```sql
CREATE DATABASE my_database;
```
このコマンドは、my_database という名前の新しいデータベースを作成します。

## テーブルの作成とスキーマの定義

テーブルはデータベース内でデータを格納するための構造です。テーブルは行（レコード）と列（フィールド）で構成されます。スキーマは、テーブル内の列の名前やデータ型を定義するものです。

以下の例では、`users` という名前のテーブルを作成し、いくつかの列を定義しています。

```sql
CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL,
    email VARCHAR(100) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
```

- `id` : ユーザーの一意の識別子。自動的に増加する整数
- `username` : ユーザー名。最大50文字の文字列
- `email` : ユーザーのメールアドレス。最大100文字の文字列
- `created_at` : レコードが作成された日時。デフォルトで現在のタイムスタンプが使用される

## テーブルの操作

作成したテーブルにデータを挿入、更新、削除する基本的なSQLコマンドは以下の通りです。

- **データの挿入** : 新しいデータをテーブルに追加
```sql
  INSERT INTO users (username, email) VALUES ('example_user', 'user@example.com');
```
- **データの更新** : テーブルの既存のデータを更新
```sql
  UPDATE users SET email = 'new_email@example.com' WHERE id = 1;
```
- **データの削除** : テーブルからデータを削除
```sql
  DELETE FROM users WHERE id = 1;
```
# SELECTクエリの基本

このセクションでは、SQLの中でも最も基本的かつ重要な操作の一つであるSELECTクエリについて学びます。SELECTクエリはデータベースから特定のデータを選択し、表示するために使用されます。また、WHERE句を使用することで、特定の条件にマッチするデータのみをフィルタリングして取得することができます。

## データの選択

データを選択する基本的なSQLコマンドは以下の通りです。

```sql
SELECT column1, column2 FROM table_name;
```

ここで、`column1`, `column2`はテーブル`table_name`から取得したい列の名前です。全ての列を選択したい場合は、以下のようにアスタリスク（`*`）を使用します。

```sql
SELECT * FROM table_name;
```

これにより、テーブル内の全ての列と行が表示されます。

## WHERE句を使ったデータのフィルタリング

特定の条件を満たすデータのみを選択するには、WHERE句を使用します。以下はその具体的な例です。

```sql
SELECT * FROM users WHERE age > 18;
```

このクエリは`users`テーブルから`age`が18より大きいすべてのユーザーの情報を選択します。条件はより複雑にすることも可能で、複数の条件を`AND`や`OR`で組み合わせることができます。

```sql
SELECT username, email FROM users WHERE age >= 18 AND active = 1;
```

上記のクエリでは、18歳以上でアカウントがアクティブな（`active = 1`）ユーザーの`username`と`email`のみを選択します。

## ソートと制限

クエリの結果を特定の順序で取得したい場合、`ORDER BY`句を使用します。また、取得するデータの数を制限したい場合は`LIMIT`句を利用します。

```sql
SELECT * FROM users WHERE age >= 18 ORDER BY age DESC LIMIT 10;
```

この例では、18歳以上のユーザーを年齢の降順で並べ替え、上位10件のみを表示します。

これらの基本的なSELECTクエリの使用方法をマスターすることで、データベースから必要な情報を効果的に取得することができます。
# データの挿入、更新、削除

このセクションでは、データベース内のデータを操作するための基本的なSQLステートメントについて学びます。具体的には、データの挿入（INSERT）、更新（UPDATE）、削除（DELETE）の方法を詳しく解説します。

## データの挿入（INSERT）

データベースに新しいレコードを追加するには、INSERTステートメントを使用します。以下にその基本的な形式を示します。

```sql
INSERT INTO table_name (column1, column2, column3, ...)
VALUES (value1, value2, value3, ...);
```

例えば、`users`テーブルに新しいユーザーを追加する場合のクエリは以下のようになります。

```sql
INSERT INTO users (username, email, age)
VALUES ('john_doe', 'john.doe@example.com', 28);
```

このコマンドは`users`テーブルに新しい行を追加し、指定された各列に対応する値を設定します。

## データの更新（UPDATE）

データベース内の既存のデータを変更するには、UPDATEステートメントを使用します。このステートメントでは、どのテーブルのどのデータをどのように更新するかを指定します。

```sql
UPDATE table_name
SET column1 = value1, column2 = value2, ...
WHERE condition;
```

例として、`users`テーブルの特定のユーザーのメールアドレスを更新するクエリは以下の通りです。

```sql
UPDATE users
SET email = 'new.email@example.com'
WHERE username = 'john_doe';
```

このクエリは`users`テーブルで`username`が`john_doe`の行を見つけ、その`email`列の値を更新します。

## データの削除（DELETE）

データベースから不要なデータを削除するには、DELETEステートメントを使用します。このコマンドは指定された条件に一致する行をテーブルから削除します。

```sql
DELETE FROM table_name
WHERE condition;
```

例えば、`users`テーブルから特定のユーザーを削除するクエリは以下の通りです。

```
DELETE FROM users
WHERE username = 'john_doe';
```

このコマンドは`users`テーブルから`username`が`john_doe`の行を削除します。

これらのステートメントを適切に使用することで、データベース内のデータを効果的に管理することができます。データの挿入、更新、削除はデータベース操作の基本であり、これらをマスターすることが重要です。


# JOINによるテーブルの結合

データベース内の異なるテーブル間で関連するデータを結合するためには、JOIN操作を使用します。このセクションでは、最も一般的に使用される三種類のJOIN、すなわちINNER JOIN、LEFT JOIN、RIGHT JOINについて学びます。

## INNER JOIN

INNER JOINは、二つのテーブル間で条件に一致する行のみを結合する操作です。このタイプのJOINでは、両方のテーブルにマッチするデータのみが結果に含まれます。

以下は`users`テーブルと`orders`テーブルを`user_id`を使って結合する例です。

```sql
SELECT users.username, orders.order_date
FROM users
INNER JOIN orders ON users.id = orders.user_id;
```

このクエリは、`users`テーブルの`id`が`orders`テーブルの`user_id`に一致するすべてのユーザーのユーザー名と注文日を取得します。

## LEFT JOIN

LEFT JOIN（またはLEFT OUTER JOIN）は、左側のテーブル（FROM句に最初に記述されたテーブル）のすべての行と、右側のテーブル（JOIN句に記述されたテーブル）のマッチする行を結合します。マッチする行が存在しない場合は、右側のテーブルの列にはNULLがセットされます。

以下のクエリは`users`テーブルのすべてのユーザーと、それに対応する注文（存在する場合）を取得します。

```sql
SELECT users.username, orders.order_date
FROM users
LEFT JOIN orders ON users.id = orders.user_id;
```

このクエリでは、注文がないユーザーの`order_date`はNULLとして表示されます。

## RIGHT JOIN

RIGHT JOIN（またはRIGHT OUTER JOIN）は、LEFT JOINの逆で、右側のテーブルのすべての行と、左側のテーブルのマッチする行を結合します。マッチする行が存在しない場合は、左側のテーブルの列にNULLがセットされます。

以下の例では、`orders`テーブルのすべての注文と、それに対応するユーザー（存在する場合）を取得します。

```sql
SELECT users.username, orders.order_date
FROM users
RIGHT JOIN orders ON users.id = orders.user_id;
```

このクエリでは、ユーザーが存在しない注文の`username`はNULLとして表示されます。

これらのJOIN操作を理解し適切に使用することで、複数のテーブルから関連する情報を効率的に抽出し、データ分析やレポート作成に役立てることができます。

# 集約関数とグループ化

データベース内のデータを集計する際には、集約関数を用いることが一般的です。これには、COUNT、SUM、AVG（平均）、MAX（最大値）、MIN（最小値）などがあります。これらの関数を利用することで、大量のデータから有意義な情報を抽出することができます。また、GROUP BY句を使ってデータをグループ化し、各グループに対して集約関数を適用することが可能です。

## 基本的な集約関数

以下は、いくつかの一般的な集約関数の使用例です。

- **COUNT**: テーブル内の行数をカウントします。
```sql
  SELECT COUNT(*) FROM users;
```
  このクエリは`users`テーブルの総行数を返します。

- **SUM**: 特定の列の値の合計を計算します。
```sql
  SELECT SUM(salary) FROM employees;
```
  このクエリは`employees`テーブルにおける`salary`列の値の合計を返します。

- **AVG**: 列の平均値を計算します。
```sql
  SELECT AVG(salary) FROM employees;
```
  このクエリは`employees`テーブルの`salary`の平均値を計算します。

- **MAX**と**MIN**: 列の最大値と最小値を見つけます。
```sql
  SELECT MAX(salary), MIN(salary) FROM employees;
```
  このクエリは`employees`テーブルの`salary`列の最大値と最小値を返します。

## GROUP BY句の使用

データを特定のカテゴリに基づいてグループ化し、各グループに対して集約関数を適用するには、GROUP BY句を使用します。

```sql
SELECT department, AVG(salary)
FROM employees
GROUP BY department;
```

このクエリでは、`employees`テーブルの`department`ごとに`salary`の平均値を計算します。結果として、各部門の平均給与が表示されます。

## 複雑なクエリの例

集約関数とGROUP BY句を組み合わせることで、より複雑なデータ分析が可能になります。例えば、各部門で給与が最も高い従業員の名前と給与を取得するには、以下のようなクエリが使用できます。

```sql
SELECT department, MAX(salary), employee_name
FROM employees
GROUP BY department;
```

これにより、各部門の最高給与とその従業員の名前が得られます。ただし、SQLの仕様によっては、全ての列をGROUP BY句に含めるか、集約関数でラップする必要があるため、このクエリは特定の環境では機能しない場合があります。

集約関数とGROUP BY句の理解と適用は、データ分析における強力なツールです。これらをマスターすることで、データからより深い洞察を得ることが可能になります。

# 最後に
最後までお付き合いいただきありがとうございました。
私自身まだまだ勉強中なので、何か問題を見つけたり、改善点があれば、勉強したいので教いただけたらと思います！