SQLのDMLについて

## はじめに

こんにちは！今回は、**SQLのDML（Data Manipulation Language）**についてまとめます。DMLは、データベースに格納されたデータを**検索・挿入・更新・削除**するための重要な機能群であり、日々の業務アプリケーション開発やデータ活用に欠かせません。

## 本文

### 1. SQL-DMLとは？

SQL-DMLは、以下の4つの基本文から構成されます。

1. **SELECT**: データの検索・取得  
2. **INSERT**: データの挿入  
3. **UPDATE**: データの更新  
4. **DELETE**: データの削除  

いずれも、データベースの表（またはビュー）を対象として操作を行います。

### 2. SELECT文

**SELECT**文は、一つまたは複数のテーブルやビューから、必要なデータを取り出すための命令です。SQLの中で最も複雑な文とも言えますが、基本構文は以下の通りです。

```sql
SELECT [ALL | DISTINCT] 列リスト
  FROM 表名 [,...表名n]
  [JOIN 句]
  [WHERE 検索条件]
  [GROUP BY グループ化する列リスト]
  [HAVING グループ化後の検索条件]
  [ORDER BY 整列のキーとなる列リスト [ASC | DESC]];
```

- **SELECT句**: 取り出す列や式、集約関数を指定
- **FROM句**: 対象となるテーブルやビューを列挙
- **JOIN句**: テーブル結合を行う場合に使用（内部結合、外部結合、交差結合など）
- **WHERE句**: 行を絞り込む検索条件
- **GROUP BY句**: 集約関数を使用する場合、グループ化の対象となる列を指定
- **HAVING句**: グループ化後の集約結果に対する検索条件
- **ORDER BY句**: 取得した行を並べ替える

#### 使用例

```sql
SELECT DISTINCT 顧客ID, 顧客名
  FROM 顧客
  WHERE 地域 = '関東'
  ORDER BY 顧客名 ASC;
```

ここでは、「関東」地域の顧客を**重複なく**取り出し、顧客名の昇順で表示しています。

#### WHERE句で使われる検索条件一覧

WHERE句でよく使われる代表的な検索条件を一覧です。実際の使用シーンに応じて、複数の条件を組み合わせたり、AND/ORなどを併用して柔軟な抽出します。

| 条件種別               | 概要                                                           | 例文                                                                                 |
|------------------------|----------------------------------------------------------------|--------------------------------------------------------------------------------------|
| **比較演算**           | `=`, `<`, `>`, `<=`, `>=`, `<>`（等しい/小なり/大なりなど）     | `WHERE 年齢 >= 20`<br>`WHERE 地域 <> '関西'`                                         |
| **論理演算**           | `AND`, `OR`, `NOT`などで条件を結合・否定                       | `WHERE 地域='関東' AND 年齢<30`<br>`WHERE NOT(地域='北海道')`                        |
| **NULL検査**           | `IS NULL` / `IS NOT NULL`                                      | `WHERE メールアドレス IS NULL`<br>`WHERE 電話番号 IS NOT NULL`                       |
| **LIKEパターンマッチ** | 文字列パターンの一部一致検索。`%`は任意の文字列、`_`は1文字     | `WHERE 名前 LIKE '山田%'`<br>`WHERE 商品名 LIKE '_C%'`                                |
| **BETWEEN範囲検査**    | 列が特定範囲内に含まれるかを判定                                 | `WHERE 価格 BETWEEN 100 AND 2000`                                                   |
| **IN範囲検査**         | 列が指定した値リストのいずれかと一致するかを判定               | `WHERE 地域 IN ('関東','関西','東北')`                                              |
| **EXISTS検査**         | サブクエリで何らかの行が返るか否かを判定                       | `WHERE EXISTS (SELECT * FROM 発注 WHERE 発注.商品ID = 商品.商品ID)`                 |
| **SOME / ANY / ALL**   | サブクエリの結果に対して、列が"いずれかに合致する/すべてに合致" | `WHERE 価格 > ANY(SELECT 価格 FROM 競合商品)`<br>`WHERE 在庫数 < ALL(SELECT ... )` |

- **比較演算**: 値の等価/大小比較を行います
- **論理演算**: 条件を組み合わせて複雑な検索条件を作成可能です
- **NULL検査**: 列の値がNULLか否かを判定します
- **LIKEパターンマッチ**: 文字列の部分一致検索に用い、ワイルドカード `%` や `_` が使用可能です
- **BETWEEN / IN**: 値がある範囲や指定リストに含まれるか判定
- **EXISTS**: サブクエリが結果を返すかどうかで真偽を判定
- **SOME / ANY / ALL**: サブクエリで返された複数の値に対し、1つでも合致/すべて合致するかを判定

### 3. INSERT文

**INSERT**文は、テーブルやビューに新しい行を追加するために使用します。

```sql
-- 構文
INSERT INTO テーブル名 [(列リスト)]
VALUES (値1 [, 値2, ...]);
```

#### 使用例

```sql
-- 列指定あり
INSERT INTO 顧客 (顧客ID, 顧客名, 地域)
VALUES (1001, '山田太郎', '関東');

-- 列指定なし（テーブル列の定義順に合わせる）
INSERT INTO 顧客
VALUES (1002, '佐藤花子', '関西');
```

- 別のテーブルからSELECTした結果を一度にINSERTすることもできます

```sql
-- 例
INSERT INTO 顧客履歴 (顧客ID, 顧客名, 地域)
SELECT 顧客ID, 顧客名, 地域
  FROM 顧客
  WHERE 地域 = '関東';
```

### 4. UPDATE文

**UPDATE**文は、テーブルやビュー上の既存データを変更するために使用します。

```sql
-- 構文
UPDATE テーブル名
   SET 列名1 = 値1 [, ... 列名n = 値n]
 [WHERE 検索条件];
```

#### 使用例

```sql
-- 例
UPDATE 顧客
   SET 地域 = '関東'
 WHERE 顧客ID = 1002;
```

- **WHERE句**を省略すると、テーブル内の全行が対象となるため要注意

### 5. DELETE文

**DELETE**文は、テーブルやビューから行を削除するために使用します。

```sql
-- 構文
DELETE FROM テーブル名
[WHERE 検索条件];
```

#### 使用例

```sql
-- 例
DELETE FROM 顧客
 WHERE 地域 = '北海道';
```

- こちらも **WHERE句を省略**すると、テーブルの全行を削除するため慎重に扱う必要があります

### 6. SQL-DMLで使用される主な機能

#### 6.1 集約（集計）関数

表の行をまとめて集計したい場合に用いられる関数です。`GROUP BY`と組み合わせて多用します。

| 関数       | 目的                                              |
|------------|---------------------------------------------------|
| **AVG**    | 数値列の平均値                                    |
| **COUNT**  | 行数または指定列の値がNULLでない件数              |
| **MAX**    | 列の最大値                                        |
| **MIN**    | 列の最小値                                        |
| **SUM**    | 数値列の合計                                      |

#### 使用例（集計）

```sql
-- 例
SELECT 地域, COUNT(*) AS 地域ごとの顧客数, AVG(年齢) AS 平均年齢
  FROM 顧客
 GROUP BY 地域
 HAVING COUNT(*) > 10;
```

上記は各地域ごとの顧客数と平均年齢を求め、10件以上の地域だけを表示しています。

---

#### 6.2 集合演算

SQLでは、複数のSELECT結果を**和（UNION）**、**差（EXCEPT）**、**共通（INTERSECT）** といった集合演算で結合できます（列数やデータ型が同じであることが前提）

```sql
-- 例
SELECT 列リスト FROM テーブルA
UNION
SELECT 列リスト FROM テーブルB;
```

- **UNION**: 2つのSELECT結果の和集合  
- **INTERSECT**: 2つのSELECT結果の共通集合  
- **EXCEPT**: 1つ目のSELECT結果から2つ目に含まれる行を除外

`UNION ALL` や `INTERSECT ALL`, `EXCEPT ALL` を使うと、重複行をまとめずにそのまま表示します。

## まとめ

**SQL-DML**は、データベースの操作において最も頻繁に使う基本命令群です。

1. **SELECT**: 必要なデータを取り出し、集計や並べ替えを行う
2. **INSERT**: 新しい行をテーブルへ追加
3. **UPDATE**: 既存の行を更新
4. **DELETE**: 既存の行を削除

さらに、**集約関数**や**集合演算**などを組み合わせることで、柔軟で高度な問い合わせや操作が可能になります。データ分析やアプリケーション開発でよく使う部分なので、各構文やオプションをしっかり把握しておくと、効率よくデータベースを活用できます。