# SQL データ操作編
###### tags: `SQL`
参考: https://sql.main.jp
## SQL が持つ機能
- データ定義
- データ操作
- データ制御
### データ操作
- `SELECT`: テーブルからデータを抽出
- `INSERT`: テーブルにレコードを追加
- `UPDATE`: テーブルのレコード内にあるデータを更新
- `DELETE`: テーブルにあるレコードを削除
## テーブルとデータ
**テーブル**とは複数のデータのまとまりのことであり、横方向のデータのまとまりを**レコード**、縦方向のデータのまとまりを**カラム**と呼ぶ。
また、レコードが持つそれぞれの単一のデータを**フィールド**と呼ぶ。
本書では以下の EMP テーブルを使ってテーブルの操作について記す。
|EMPNO|ENAME|JOB|MGR|HIREDATE|SAL|COMM|DEPTNO|
|---|---|---|---|---|---|---|---|
|7369|SMITH|CLERK|7902|1980-12-17|800|300|20|
|7499|ALLEN|SALESMAN|7698|1981-02-20|1600|300|30|
|7521|WARD|SALESMAN|7698|1981-02-22|1250|500|30|
|7566|JONES|MANAGER|7839|1981-04-02|2975||20|
|7654|MARTIN|SALESMAN|7698|1981-09-28|1250|1400|30|
|7698|BLAKE|MANAGER|7839|1981-05-01|2850||30|
|7782|CLARK|MANAGER|7839|1981-06-09|2450||10|
|7839|KING|PRESIDENT||1981-11-17|5000||10|
|7844|TURNER|SALESMAN|7698|1981-09-08|1500|0|30|
|7900|JAMES|CLERK|7698|1981-12-03|950||30|
|7902|FORD|ANALYST|7566|1981-12-03|3000||20|
|7934|MILLER|CLERK|7782|1982-01-23|1300||10|
## `SELECT`
### 基本の構文
EMP テーブルから従業員名(ENAME)、仕事(JOB)、給料(SAL)を取得。
```sql!
SELECT ENAME, JOB, SAL
FROM EMP
```
### `*`
EMP テーブルからすべてのレコードを取得。
```sql!
SELECT *
FROM EMP
```
### 算術演算子
EMP テーブルから従業員名(ENAME)と1.02倍した給料(SAL)を取得。
```sql!
SELECT NAME, SAL * 1.02
FROM EMP
```
### `WHERE` と比較演算子
EMP テーブルから部署番号(DEPTNO)が 20 の従業員名(ENAME)を取得。
```sql!
SELECT ENAME
FROM EMP
WHERE DEPTNO = 20
```
### 複合条件と論理演算子
EMP テーブルから、仕事(JOB)が CLERK か SALESMAN の従業員名(ENAME)とその JOB を取得。
```sql!
SELECT ENAME, JOB
FROM EMP
WHERE JOB = 'CLERK' OR JOB = 'SALESMAN'
```
### ソート
EMP テーブルから従業員名(ENAME)と仕事(JOB)と給料(SAL)を、SAL の降順にソートして取得。
```sql!
SELECT ENAME, JOB, SAL
FROM EMP
ORDER BY SAL DESC
```
### 集合関数
EMP テーブルから給料(SAL)の総和、最大値、最小値、平均値、総数を取得。
```sql!
SELECT SUM(SAL), MAX(SAL), MIN(SAL), AVG(SAL), COUNT(SAL)
FROM EMP
```
### `BETWEEN`
EMP テーブルから給料(SAL)が 1000 以上 2000 以下の従業員名(ENAME)と SAL を取得。
```sql!
SELECT ENAME, SAL
FROM EMP
WHERE SAL BETWEEN 1000 AND 2000
```
### `IN`
以下の `DEPTNO IN (10,30)` は `DEPTNO = 10 OR DEPTNO = 30` と同じ意味。
```sql!
SELECT *
FROM EMP
WHERE DEPTNO IN (10,30)
```
### `LIKE`
EMP テーブルから従業員名(ENAME)に「A」を含む ENAME と給料(SAL)を取得。
```sql!
SELECT ENAME, SAL
FROM EMP
WHERE ENAME LIKE '%A%'
```
### `GROUP BY`
EMP テーブルから部署番号(DEPTNO)ごとに、DEPTNO と給料(SAL)の平均を取得。
```sql!
SELECT DEPTNO, AVG(SAL)
FROM EMP
GROUP BY DEPTNO
```
### 重複行の排除
EMP テーブルから仕事(JOB)が重複している行を取り除きながら取得。
```sql!
SELECT DISTINCT JOB
FROM EMP
```
## `INSERT`
### 基本の構文
EMP テーブルに新しいレコードを値を指定しつつ追加。
```sql!
INSERT INTO EMP (EMPNO, NAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
VALUES (9999, 'SAN', 'SALESMAN', 7698, 1981-09-28, 1000, 500, 10)
```
### 別の表からの追加
EMP_TEMP テーブルから EMP テーブルに新しいレコードを選択して追加。
```sql!
INSERT INTO EMP_TEMP
SELECT *
FROM EMP
WHERE JOB = 'SALESMAN'
```
## `UPDATE`
### 基本の構文
EMP テーブルの部署番号(DEPTNO)が 20 の仕事(JOB)と DEPTNO を更新。
```sql!
UPDATE EMP
SET JOB = SALESMAN, DEPTNO = 25
WHERE DEPTNO = 20
```
### 算術演算子を使って更新
EMP テーブルで従業員番号(EMPNO)が 7369 の給料(SAL)を 1.5 倍に更新。
```sql!
UPDATE EMP
SET SAL = SAL * 1.5
WHERE EMPNO = 7369
```
## `DELETE`
### 基本の構文
EMP テーブルから従業員番号(EMPNO)が 7782 のレコードを削除。
```sql!
DELETE FROM EMP
WHERE EMPNO = 7782
```
## 複数のテーブルを組み合わせたデータの取得
本項ではさらに以下の DEPT テーブルと組み合わせた問い合わせ方法について記す。
|DEPTNO|DNAME|LOC|
|---|---|---|
|10|ACCOUNTING|NEW|YORK|
|20|RESEARCH|DALLAS|
|30|SALES|CHICAGO|
|40|OPERATIONS|BOSTON|
### 条件結合
EMP テーブルと DEPT テーブルで一致する部署番号(DEPTNO)を持つ従業員番号(EMPNO)、従業員名(ENAME)、DEPTNO、部署名(DNAME)を取得。
```sql!
SELECT EMP.EMPNO, EMP.ENAME, DEPT.DEPTNO, DEPT.DNAME
FROM EMP, DEPT
WHERE EMP.DEPTNO = DEPT.DEPTNO
```
### エイリアス
`FROM` ではテーブル名に別名をつけることができる。
```sql!
SELECT E.EMPNO, E.ENAME, D.DEPTNO, D.DNAME
FROM EMP E, DEPT D
WHERE E.DEPTNO = D.DEPTNO
```
### 副問い合わせ
最小の部署番号(DEPTNO)の従業員レコードを取得。
```sql!
SELECT *
FROM EMP
WHERE EMP.DEPTNO = (
SELECT MIN(DEPT.DEPTNO)
FROM DEPT
)
```
### 入れ子の `IN`
`IN` の中で入れ子の構造を作ると以下のようになる。
```sql!
SELECT *
FROM EMP
WHERE DEPTNO IN (
SELECT DEPTNO
FROM DEPT
WHERE DNAME
LIKE '%S%'
)
```
### `EXISTS`
給料(SAL)がもっとも高い従業員名(ENAME)を取得。
```sql!
SELECT ENAME, SAL
FROM EMP EA
WHERE NOT EXISTS(
SELECT *
FROM EMP EB
WHERE EB.SAL > EA.SAL
)
```