理解度チェック問題：H2 Database（H2DB）を使用したSQLチュートリアル

# 理解度チェック問題：H2 Database（H2DB）を使用したSQLチュートリアル

このセクションでは、**H2 Database（H2DB）**を使用したSQLチュートリアルの各項目に対応する問題を提供します。これらの問題に取り組むことで、学習内容の理解度を確認し、実践的なスキルを向上させることができます。問題の後に解答例を掲載していますので、自己採点にご利用ください。

---

## 1. リレーショナルデータベースとSQLの概要

### 問題1：リレーショナルデータベースの基本概念

**Q1:** リレーショナルデータベースの主な特徴として正しいものを選んでください。

A. データはファイルシステム上にフラットに保存される  
B. データはテーブル形式で管理され、行と列から構成される  
C. データ間の関係性はプログラムコードで管理される  
D. リレーショナルデータベースではデータの整合性を保証しない  

---

### 問題2：SQLのカテゴリ

**Q2:** SQLの中で、データベースやテーブルの構造を定義・変更するための言語はどれですか？

A. DML（データ操作言語）  
B. DDL（データ定義言語）  
C. DCL（データ制御言語）  
D. TCL（トランザクション制御言語）  

---

## 2. SQLによるデータ検索

### 2.1 全件検索

**Q3:** `products` テーブルからすべてのカラムとレコードを取得するSQL文を記述してください。

---

### 2.2 探索条件

**Q4:** `employees` テーブルから、年齢が30歳以上で部署が「Sales」の従業員を取得するSQL文を記述してください。

---

### 2.3 結合

**Q5:** `employees` テーブルと `departments` テーブルを `dept_id` で内部結合し、従業員の名前と所属部署名を取得するSQL文を記述してください。

---

### 2.4 集合関数

**Q6:** `orders` テーブルにおける全注文の合計金額を計算するSQL文を記述してください。

---

### 2.5 グループ化

**Q7:** 各部署ごとの従業員数を取得するためのSQL文を記述してください。

---

### 2.6 並び替え

**Q8:** `users` テーブルから全ユーザーを作成日時の降順で取得するSQL文を記述してください。

---

### 2.7 集合演算

**Q9:** `current_users` と `former_users` の両方に存在するユーザー（`username` と `email` が一致するもの）を取得するSQL文を記述してください。

---

### 2.8 副問合せ

**Q10:** `employees` テーブルから、平均給与以上の給与を受け取っている従業員の名前と給与を取得するSQL文を記述してください。

---

## 3. SQLによるデータ追加/更新/削除

### 問題11：データの追加（INSERT）

**Q11:** `customers` テーブルに新しい顧客「Ivy Nelson」を、メールアドレス「ivy.nelson@example.com」、電話番号「555-3456」、住所「321 Birch Lane」で追加するSQL文を記述してください。

---

### 問題12：データの更新（UPDATE）

**Q12:** `products` テーブルで「Laptop」の在庫数を10から15に更新するSQL文を記述してください。

---

### 問題13：データの削除（DELETE）

**Q13:** `orders` テーブルから、注文日が「2024-04-18」の注文を削除するSQL文を記述してください。

---

## 4. 実践問題

### 問題14：複合クエリ

**Q14:** `orders` テーブルと `order_items` テーブルを結合し、各注文の合計金額（`quantity` × `price` の合計）を計算して表示するSQL文を記述してください。

---

### 問題15：サブクエリの活用

**Q15:** `employees` テーブルから、最も高い給与を受け取っている従業員の名前と給与を取得するSQL文を記述してください。（サブクエリを使用）

---

---

## 解答例

### 解答1:
**B**  
リレーショナルデータベースは、データをテーブル形式で管理し、行と列から構成されます。

---

### 解答2:
**B**  
Ddl（データ定義言語）は、データベースやテーブルの構造を定義・変更するための言語です。

---

### 解答3:
```sql
SELECT * FROM products;
```

---

### 解答4:
```sql
SELECT * FROM employees
WHERE age >= 30 AND dept_id = (
    SELECT dept_id FROM departments WHERE dept_name = 'Sales'
);
```
*注: `departments` テーブルから「Sales」部署の `dept_id` を取得しています。*

---

### 解答5:
```sql
SELECT employees.name, departments.dept_name
FROM employees
INNER JOIN departments ON employees.dept_id = departments.dept_id;
```

---

### 解答6:
```sql
SELECT SUM(price) AS total_sales FROM orders;
```

---

### 解答7:
```sql
SELECT departments.dept_name, COUNT(employees.emp_id) AS num_employees
FROM employees
INNER JOIN departments ON employees.dept_id = departments.dept_id
GROUP BY departments.dept_name;
```

---

### 解答8:
```sql
SELECT * FROM users
ORDER BY created_at DESC;
```

---

### 解答9:
```sql
SELECT current_users.username, current_users.email
FROM current_users
INNER JOIN former_users
ON current_users.username = former_users.username
AND current_users.email = former_users.email;
```

---

### 解答10:
```sql
SELECT name, salary
FROM employees
WHERE salary >= (
    SELECT AVG(salary) FROM employees
);
```

---

### 解答11:
```sql
INSERT INTO customers (customer_name, email, phone, address)
VALUES ('Ivy Nelson', 'ivy.nelson@example.com', '555-3456', '321 Birch Lane');
```

---

### 解答12:
```sql
UPDATE products
SET stock = 15
WHERE product_name = 'Laptop';
```

---

### 解答13:
```sql
DELETE FROM orders
WHERE order_date = '2024-04-18';
```

---

### 解答14:
```sql
SELECT orders.order_id, SUM(order_items.quantity * order_items.price) AS total_amount
FROM orders
INNER JOIN order_items ON orders.order_id = order_items.order_id
GROUP BY orders.order_id;
```

---

### 解答15:
```sql
SELECT name, salary
FROM employees
WHERE salary = (
    SELECT MAX(salary) FROM employees
);
```

---

---

## 解答解説

### 問題1解説:
リレーショナルデータベースは、データをテーブル形式で管理し、行と列から構成されます。他の選択肢はリレーショナルデータベースの特徴ではありません。

### 問題2解説:
DDL（データ定義言語）は、データベースやテーブルの構造を定義・変更するための言語です。DMLはデータ操作、DCLはデータ制御、TCLはトランザクション制御に使用されます。

### 問題3解説:
`SELECT * FROM products;` は、`products` テーブルからすべてのカラムとレコードを取得する基本的な全件検索のクエリです。

### 問題4解説:
`employees` テーブルから特定の条件に一致するレコードを取得するために、`WHERE` 句を使用します。部署名「Sales」を取得するためにサブクエリを使用しています。

### 問題5解説:
`INNER JOIN` を使用して `employees` と `departments` を `dept_id` で結合し、従業員の名前と所属部署名を取得しています。

### 問題6解説:
`SUM(price)` を使用して `orders` テーブルの全注文金額の合計を計算しています。

### 問題7解説:
`GROUP BY` 句を使用して各部署ごとに従業員数をカウントしています。`COUNT(employees.emp_id)` で従業員数を計算しています。

### 問題8解説:
`ORDER BY created_at DESC` を使用して `users` テーブルから取得したユーザーを作成日時の降順で並び替えています。

### 問題9解説:
`current_users` と `former_users` の両方に存在するユーザーを `INNER JOIN` で取得しています。`username` と `email` の両方が一致するレコードを選択しています。

### 問題10解説:
サブクエリを使用して `employees` テーブルの平均給与を計算し、その値以上の給与を受け取っている従業員を取得しています。

### 問題11解説:
`INSERT INTO` 文を使用して `customers` テーブルに新しい顧客情報を追加しています。必要なカラムに対して値を指定しています。

### 問題12解説:
`UPDATE` 文を使用して `products` テーブルの「Laptop」の在庫数を更新しています。`WHERE` 句で特定の製品を指定しています。

### 問題13解説:
`DELETE FROM` 文を使用して `orders` テーブルから特定の日付の注文を削除しています。`WHERE` 句で削除するレコードを指定しています。

### 問題14解説:
`orders` テーブルと `order_items` テーブルを `INNER JOIN` で結合し、各注文の合計金額を計算しています。`GROUP BY` 句で注文ごとにグループ化しています。

### 問題15解説:
サブクエリを使用して `employees` テーブルの最高給与を取得し、その給与と一致する従業員の名前と給与を取得しています。

---

## まとめ

この問題セットを通じて、**H2 Database（H2DB）**を活用したSQLの基本から応用までの理解を深めることができます。各問題に取り組むことで、実際のデータベース操作に必要なスキルを実践的に習得しましょう。疑問点があれば、チュートリアルや公式ドキュメントを参照し、さらなる学習を続けてください。

---

**参考リンク**

- [H2 Database 公式サイト](https://www.h2database.com/)
- [H2 Database ドキュメント](https://www.h2database.com/html/documentation.html)
- [SQL Tutorial - W3Schools](https://www.w3schools.com/sql/)
- [SQL Reference - H2 Documentation](https://www.h2database.com/html/commands.html)

---

**サポート**

問題に取り組む中で不明点や問題が発生した場合は、以下のリソースを活用してサポートを受けてください：

- **公式フォーラム**: [H2 Database フォーラム](https://groups.google.com/g/h2-database)
- **Stack Overflow**: [H2 Database タグ](https://stackoverflow.com/questions/tagged/h2)
- **ドキュメント参照**: [H2 Database 詳細ドキュメント](https://www.h2database.com/html/documentation.html)

継続的な学習と実践により、より高度なデータベース管理とSQLクエリのスキルを身につけましょう。頑張ってください！