[WIP]MySQL 入門

:::note info
趣旨
初級・初心者レベルの基本文のみの掲載になるので、真新しい発見や深掘りした内容ではありません。個人目標としてどういったデータが必要か、どのような構造にするべきかの設計を学びたいのですが、その前にデータを扱う基礎の部分を理解したところまで綴っていきます。
使用エディタ：eclips
データベース：MySQL
:::

# データの操作 DML
- SELECT 文
- INSERT 文
- UPDATE 文
- DELETE 文

# SELECT でできること
データベースからデータを検索する際に使用します。
そのため、データベースが存在してる（CREATE TABLE 済）ことが前提です。

| 機能 | 説明 |
| ---- | ---- |
| 射影 | SELECT 文を用いて表の中のどの列を検索するかを指定します。 |
| 選択 | SELECT 文を用いて表の中のどの行を検索するかを指定します。 |
| 結合 | SELECT 文を用いて複数の表に格納されているデータを関連付けて表示します。 |

## 表から「特定の列」を取得したい（射影）
### SELECT 列名 FROM 表名

`SELECT` で「列名」を指定し、`FROM` で対象の「表名」を指定します。
これで表の中から取得したい列を抽出できます。

```sql:構文
SELECT 列名[, 列名…] FROM 表名;
```
```sql:MySQL Sample
-- 例：表「社員名簿 employees」から列「社員番号 empno」を取得する
SELECT empno FROM employees;
```
取得したい列が複数ある場合、列名をカンマ（,）区切りで列挙できます。
```sql:MySQL Sample
-- 例：表「社員名簿 employees」から列「社員番号 empno」と「社員名 emname」を取得する
SELECT empno, emname FROM employees;
```
表内のすべての列を取得したい場合、列名の代わりに「アスタリスク（*）」を使用します。
```sql:MySQL Sample
-- 例：表「社員名簿」から「すべての列 *」を取得する
SELECT * FROM employees;
```
## 表から「特定の列」の中で「条件にあてはまる行」を取得したい（選択）

単純に列名を表示するだけではなく、その列から「特定の条件が含まれた行」を取得したい場合、その条件を `WHERE 句` で記述します。検索条件文には演算子を使います。なお文字列を指定したい場合、`'シングルクォーテーション'` で囲みます。
```sql:構文
SELECT 列名 FROM 表名 WHERE 検索条件;
```
### WHERE 検索条件
`WHERE 句` の後に条件を記述します。条件には演算子を使います。

#### 比較演算子
行データと値を比較し、その条件にあてはまる列を取得できます。

```sql:MySQL Sample「=」
-- 例：社員名簿表から社員名 emname が mamiline6 の条件で取得する
-- SELECT * FROM employees
WHERE emname = 'mamiline6';
```
```sql:MySQL Sample「>」
-- 例：社員名簿表から給与 sal が 600,000円 より大きい条件で取得する
-- SELECT * FROM employees
WHERE sal > 600000;
```
```sql:MySQL Sample「>=」
-- 例：社員名簿表から給与 sal が 600,000円 以上の条件で取得する
-- SELECT * FROM employees
WHERE sal >= 600000;
```
```sql:MySQL Sample「<」
-- 例：社員名簿表から給与 sal が 400,000円 より小さい条件で取得する
-- SELECT * FROM employees
WHERE sal < 400000;
```
```sql:MySQL Sample「<=」
-- 例：社員名簿表から給与 sal が 400,000円 以下の条件で取得する
-- SELECT * FROM employees
WHERE sal <= 400000;
```
```sql:MySQL Sample「!=」
-- 例：社員名簿表から給与 sal が 400,000円 ではない条件で取得する
-- SELECT * FROM employees
WHERE sal != 400000;
```

#### 論理演算子

比較演算子は、条件を一つだけしか指定できませんが、論理演算子を使うと、比較する条件を複数指定できます。
```sql:MySQL Sample「AND」
-- 例：社員名簿表から給与 sal が 300,000円、かつ 部署番号 job_id が 30 の条件で取得する
-- SELECT * FROM employees
WHERE sal = 300000 AND job_id = '30';
```
```sql:MySQL Sample「OR」
-- 例：社員名簿表から給与 sal が 300,000円、または 部署番号 job_id が 30 の条件で取得する
-- SELECT * FROM employees
WHERE sal = 300000 OR job_id = '30';
```
```sql:MySQL Sample「NOT」
-- 例：社員名簿表から部署番号 job_id が 30 以外の条件で取得する
-- SELECT * FROM employees
WHERE NOT job_id = '30';
```
!= と NOT の違いってなんだ？

## 表から「重複行を除いた」列を取得したい
### DISTINCT 列名
列から重複した行データごとにまとめて単一の行として表示します。
```sql:構文
SELECT DISTINCT 列名 FROM 表名;
```
文章だけではイメージがつきにくいので、簡単なサンプルで表現します。
```sql: employees テーブル
+----+------+-----+
| no | name | job |
+----+------+-----+
|  1 |  澤村 |  WS |
|  2 |  菅原 |  S  |
|  3 |  東峰 |  WS |
|  4 |  西谷 |  L  |
+----+------+-----+
```
```sql:MySQL Sample
-- 例：社員名簿表から職種 job の全一覧を取得する
SELECT DISTINCT job FROM employees;
```
```sql: 実行結果
+-----+
| job |
+-----+
|  WS |
|  S  |
|  L  |
+-----+
```

## 表から「特定の条件を基準」に「行を並び変え」て取得したい

### ORDER BY 式 [ASC|DESC]
指定する式はカンマ（,）で区切ることで複数指定できます。その場合、並び替えの優先順は、記述順になります。また、文全体で登場していない列を並び替えの基準にもできます。
並び替えのデフォルト設定は、ASC（昇順・小さい順）で省略も可能です。
なお、WHERE 句は省略ができ、記述順は、ORDER BY より先に宣言する。

```sql:構文
SELECT 列名 FROM 表名
WHERE 検索条件
ORDER BY 式 [ASC|DESC];`
```
```sql:mysql Sample
-- 例：表「社員名簿」から「部署コード job_id」と「給与 sal」を元に小さい順に並び替え、社員名と給与を取得する
SELECT ename, sal FROM employees
ORDER BY job_id, sal DESC;
```
## 複数の表から列を取得したい（結合）
一つの表からの検索だけでなく、複数の表を組み合わせて検索もできます。
- 等価結合 :star::star::star:
- 非等価結合
- 自己結合 :star::star::star:
- 3つ以上の表結合 :star::star::star:
- 自然結合 :star::star::star:
- 直積演算と交差（クロス）結合
- 外部結合

## 複数の表から「ある条件が一致する場合に結合」したい（等価結合）
### JOIN 表名 ON 結合条件
- JOIN 句：２つ目の表を指定する
- ON 句：結合条件を指定する。等価結合と呼ばれる所以は、結合条件に `比較演算子 =` を使うからという。
```sql:mysql
SELECT 表A.列名, 表B.列名[,表A.列名…]
FROM 表A
JOIN 表B ON 結合条件;
```
### FROM 表名, 表名 WHERE 結合条件
```sql:mysql
SELECT 表A.列名, 表B.列名[,表A.列名…]
FROM 表A, 表B
WHERE 結合条件;
```
## 表の「特定の条件が一致する場合」に「複数の列を結合」したい（自己結合）
```sql:mysql
-- 社員名簿表 employees で社員番号列 empno と上司名列 manager が一致する場合、社員名列と上司名列を結合する
SELECT emp.name, mng.name
FROM employees emp
JOIN employees mng ON emp.empno = mng.manager;
```
## 複数の表がある条件で一致する場合に結合し、結合した表と別の表がある条件で一致した場合に結合したい

見出しのような文章表現では伝わりにくいかも・・・

```sql:mysql
SELECT 表A.列名, 表B.列名, 表C.列名[,表A.列名…]
FROM 表A
JOIN 表B ON 結合条件
JOIN 表C ON 結合条件;
```