# 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 ) ```