社員テーブルには部署IDしか入っていないので、社員の一覧に部署名を表示するには、部署テーブルとつなげて取り出す必要があります。2つのテーブルを、共通の列の値でつなげて1つの表として取り出すことを 結合(JOIN)といいます。この章では、内部結合と外部結合を学び、これまでの WHERE・集計と組み合わせます。最後に、この教材のまとめと Spring入門へ進む準備をします。
この章で学ぶこと
- 内部結合
INNER JOIN … ON …と、テーブルの別名 - 外部結合
LEFT OUTER JOINと、結合でできる NULL -
NVLで NULL を別の値に置き換える - 結合と WHERE・GROUP BY の組み合わせ
- この教材のまとめと、Spring入門との関係
10.1 なぜ結合が必要か
第1章で見たとおり、部署名は部署テーブルにだけ持たせ、社員テーブルには部署IDを持たせています。そのため、SELECT * FROM EMPLOYEE の結果には「2」や「3」という部署IDは出てきますが、「営業部」「開発部」という名前は出てきません。
社員の一覧に部署名を表示するには、社員テーブルの各行の DEPT_ID と、部署テーブルの DEPT_ID が 同じ値の行同士をつなげて、1つの表にします。これが結合です。

図10-1 DEPT_ID が同じ行同士をつなげて、部署名を持つ1つの表にする
10.2 内部結合:INNER JOIN
結合の基本の形は次のとおりです。
SELECT 列名, ...
FROM テーブル1 別名1
INNER JOIN テーブル2 別名2 ON 結合の条件;
社員の一覧に部署名を付けて取り出します。
SELECT e.EMP_ID, e.NAME, d.DEPT_NAME
FROM EMPLOYEE e
INNER JOIN DEPARTMENT d ON e.DEPT_ID = d.DEPT_ID
ORDER BY e.EMP_ID;
| EMP_ID | NAME | DEPT_NAME |
|---|---|---|
| 1 | 雷禅 海皇 | 営業部 |
| 2 | 院照 心愛 | 総務部 |
| 3 | 林檎 星飛 | 開発部 |
| 4 | 田中 美咲 | 開発部 |
| 5 | 佐藤 健太 | 営業部 |
| 6 | 鈴木 花子 | 総務部 |
| 7 | 高橋 翔 | 開発部 |
| 8 | 伊藤 さくら | 営業部 |
| 9 | 渡辺 大輔 | 営業部 |
| 10 | 中村 結衣 | 開発部 |

図10-2 結合した SELECT の結果(部署名が表示されている)
| 記述 | 意味 |
|---|---|
FROM EMPLOYEE e |
社員テーブルに e という 別名 を付ける。以降、e.NAME のように「どのテーブルの列か」を別名で示す |
INNER JOIN DEPARTMENT d |
部署テーブル(別名 d)と結合する |
ON e.DEPT_ID = d.DEPT_ID |
結合の条件。社員の DEPT_ID と部署の DEPT_ID が同じ行同士をつなげる |
e.EMP_ID, e.NAME, d.DEPT_NAME |
社員テーブルの列と部署テーブルの列を、まとめて取り出す |
結合の条件は、外部キーの列と、それが参照する主キーの列を = で結ぶのが基本です。第3章で REFERENCES DEPARTMENT (DEPT_ID) と書いた関係を、そのまま ON に書いていると考えてください。
テーブルの別名
2つのテーブルに同じ名前の列(DEPT_ID)があるので、どちらの DEPT_ID かを区別する必要があります。e.DEPT_ID・d.DEPT_ID のように 別名.列名 で書きます。別名を付けずに EMPLOYEE.DEPT_ID と書くこともできますが、長くなるので別名を付けるのが一般的です。別名は、テーブル名の後ろに空白を空けて書きます(列の別名と違い、AS は 書けません。書くとエラーになります)。
どちらか一方のテーブルにしかない列(NAME、DEPT_NAME)は、別名を省略して NAME とだけ書いても動きます。しかし、両方にある列(DEPT_ID)を別名なしで書くと、「ORA-00918: 列の定義が未確定です。」というエラーになります。この教材では、どの列がどのテーブルのものか読む人にすぐ分かるように、結合する SQL ではすべての列に別名を付けて 書きます。
すべての列を取り出す
SELECT * で結合すると、両方のテーブルのすべての列が並びます。
SELECT * FROM EMPLOYEE e INNER JOIN DEPARTMENT d ON e.DEPT_ID = d.DEPT_ID ORDER BY e.EMP_ID;
| EMP_ID | NAME | GENDER | AGE | BIRTH_DATE | DEPT_ID | ADDRESS | DEPT_ID_1 | DEPT_NAME |
|---|---|---|---|---|---|---|---|---|
| 1 | 雷禅 海皇 | 1 | 26 | 2000-06-22 00:00:00 | 2 | 大阪府 | 2 | 営業部 |
| 2 | 院照 心愛 | 2 | 27 | 1999-07-11 00:00:00 | 1 | 京都府 | 1 | 総務部 |
| 3 | 林檎 星飛 | 1 | 24 | 2001-12-24 00:00:00 | 3 | 東京都 | 3 | 開発部 |
| …(以下、10行目まで) | ||||||||
DEPT_ID が2つ(社員側と部署側)並び、値は同じです。SQL Developer では2つ目の見出しが DEPT_ID_1 のように表示されます。必要な列だけを別名付きで書いた方が、結果が読みやすくなります。
社員一覧に必要な列をすべて、部署名付きで取り出す SQL は次のようになります。これは、Spring入門の社員管理アプリが一覧画面で表示する内容と同じです。
SELECT e.EMP_ID, e.NAME, e.GENDER, e.AGE, e.BIRTH_DATE,
d.DEPT_NAME, e.ADDRESS
FROM EMPLOYEE e
INNER JOIN DEPARTMENT d ON e.DEPT_ID = d.DEPT_ID
ORDER BY e.EMP_ID;
| EMP_ID | NAME | GENDER | AGE | BIRTH_DATE | DEPT_NAME | ADDRESS |
|---|---|---|---|---|---|---|
| 1 | 雷禅 海皇 | 1 | 26 | 2000-06-22 00:00:00 | 営業部 | 大阪府 |
| 2 | 院照 心愛 | 2 | 27 | 1999-07-11 00:00:00 | 総務部 | 京都府 |
| 3 | 林檎 星飛 | 1 | 24 | 2001-12-24 00:00:00 | 開発部 | 東京都 |
| 4 | 田中 美咲 | 2 | 24 | 2002-03-05 00:00:00 | 開発部 | 愛知県 |
| 5 | 佐藤 健太 | 1 | 31 | 1995-04-12 00:00:00 | 営業部 | 東京都 |
| 6 | 鈴木 花子 | 2 | 29 | 1997-01-30 00:00:00 | 総務部 | 大阪府 |
| 7 | 高橋 翔 | 1 | 35 | 1991-08-15 00:00:00 | 開発部 | 東京都 |
| 8 | 伊藤 さくら | 2 | 22 | 2004-05-20 00:00:00 | 営業部 | 兵庫県 |
| 9 | 渡辺 大輔 | 1 | 42 | 1984-02-10 00:00:00 | 営業部 | 神奈川県 |
| 10 | 中村 結衣 | 2 | 26 | 2000-09-03 00:00:00 | 開発部 | 京都府 |
【知識メモ】JOIN の書き方のいろいろ
INNER JOIN の INNER は省略して JOIN とだけ書けます。また、古くからある書き方として、FROM EMPLOYEE e, DEPARTMENT d WHERE e.DEPT_ID = d.DEPT_ID のように、FROM にテーブルを , で並べて WHERE に結合の条件を書く形もあり、現場の既存の SQL でよく見かけます。どちらも結果は同じです。この教材では、結合の条件と絞り込みの条件がはっきり分かれる INNER JOIN … ON の形で書きます。
3つ以上のテーブルを結合する
INNER JOIN … ON … を続けて書くと、3つ以上のテーブルを結合できます。
SELECT 列名, ...
FROM テーブル1 別名1
INNER JOIN テーブル2 別名2 ON 結合の条件1
INNER JOIN テーブル3 別名3 ON 結合の条件2;
たとえば、社員テーブルに役職ID(JOB_ID)の列があり、役職テーブル(JOB)の主キーを参照しているとします。社員に部署名と役職名を付けて取り出す SQL は、次のようになります。この教材のテーブルには役職テーブルが無いので、この SQL は実行できません。
SELECT e.EMP_ID, e.NAME, d.DEPT_NAME, j.JOB_NAME
FROM EMPLOYEE e
INNER JOIN DEPARTMENT d ON e.DEPT_ID = d.DEPT_ID
INNER JOIN JOB j ON e.JOB_ID = j.JOB_ID
ORDER BY e.EMP_ID;
1つ目の結合の結果に、2つ目のテーブルを結合する、という順に読みます。結合の条件は、2つのテーブルのときと同じく、外部キーの列と、それが参照する主キーの列を = で結びます。テーブルのつながりは、ER 図(第1章)で確かめられます。
10.3 結合と WHERE を組み合わせる
結合した結果を WHERE で絞り込めます。WHERE は ON の後ろに書きます。部署テーブルの列(DEPT_NAME)を条件に使えるのが、結合の利点です。開発部の社員を取り出します。
SELECT e.EMP_ID, e.NAME, d.DEPT_NAME
FROM EMPLOYEE e
INNER JOIN DEPARTMENT d ON e.DEPT_ID = d.DEPT_ID
WHERE d.DEPT_NAME = '開発部'
ORDER BY e.EMP_ID;
| EMP_ID | NAME | DEPT_NAME |
|---|---|---|
| 3 | 林檎 星飛 | 開発部 |
| 4 | 田中 美咲 | 開発部 |
| 7 | 高橋 翔 | 開発部 |
| 10 | 中村 結衣 | 開発部 |
30歳以上の社員を、部署名付きで年齢の大きい順に取り出します。
SELECT e.NAME, d.DEPT_NAME, e.AGE
FROM EMPLOYEE e
INNER JOIN DEPARTMENT d ON e.DEPT_ID = d.DEPT_ID
WHERE e.AGE >= 30
ORDER BY e.AGE DESC;
| NAME | DEPT_NAME | AGE |
|---|---|---|
| 渡辺 大輔 | 営業部 | 42 |
| 高橋 翔 | 開発部 | 35 |
| 佐藤 健太 | 営業部 | 31 |
ON には「どの行とどの行をつなげるか」の条件を、WHERE には「つなげた結果のどの行を残すか」の条件を書く、と役割を分けて考えると整理できます。
10.4 外部結合:LEFT OUTER JOIN
今度は部署を主役にして、部署ごとに所属する社員を取り出してみます。まず INNER JOIN で、部署テーブルを先に書きます。
SELECT d.DEPT_NAME, e.NAME
FROM DEPARTMENT d
INNER JOIN EMPLOYEE e ON d.DEPT_ID = e.DEPT_ID
ORDER BY d.DEPT_ID, e.EMP_ID;
| DEPT_NAME | NAME |
|---|---|
| 総務部 | 院照 心愛 |
| 総務部 | 鈴木 花子 |
| 営業部 | 雷禅 海皇 |
| 営業部 | 佐藤 健太 |
| 営業部 | 伊藤 さくら |
| 営業部 | 渡辺 大輔 |
| 開発部 | 林檎 星飛 |
| 開発部 | 田中 美咲 |
| 開発部 | 高橋 翔 |
| 開発部 | 中村 結衣 |
結果は10行で、人事部が出てきません。INNER JOIN は、両方のテーブルに相手がいる行だけ を結果に残します。人事部には社員がいない(DEPT_ID が 4 の社員がいない)ので、結果から外れました。
「社員がいない部署も、部署名だけは表示したい」というときに使うのが 外部結合 です。INNER JOIN を LEFT OUTER JOIN に変えます。
SELECT d.DEPT_NAME, e.NAME
FROM DEPARTMENT d
LEFT OUTER JOIN EMPLOYEE e ON d.DEPT_ID = e.DEPT_ID
ORDER BY d.DEPT_ID, e.EMP_ID;
| DEPT_NAME | NAME |
|---|---|
| 総務部 | 院照 心愛 |
| 総務部 | 鈴木 花子 |
| 営業部 | 雷禅 海皇 |
| 営業部 | 佐藤 健太 |
| 営業部 | 伊藤 さくら |
| 営業部 | 渡辺 大輔 |
| 開発部 | 林檎 星飛 |
| 開発部 | 田中 美咲 |
| 開発部 | 高橋 翔 |
| 開発部 | 中村 結衣 |
| 人事部 | (null) |
11行になり、人事部の行が増えました。人事部には相手の社員がいないので、社員テーブル側の列(NAME)は NULL になっています。SQL Developer では NULL は (null) と表示されます。

図10-4 LEFT OUTER JOIN の結果(人事部の NAME が (null))

図10-5 INNER JOIN と LEFT OUTER JOIN の違い
| 結合 | 結果に残る行 |
|---|---|
INNER JOIN(内部結合) |
結合の条件で 両方のテーブルに相手がいる行 だけ |
LEFT OUTER JOIN(左外部結合) |
左(FROM 側)のテーブルの全行。右に相手がいない行は、右の列が NULL になる |
「左」とは、FROM に書いたテーブル(JOIN の左側に書いたテーブル)のことです。LEFT OUTER JOIN の OUTER は省略して LEFT JOIN と書けます。右のテーブルの全行を残す RIGHT OUTER JOIN もありますが、テーブルの順番を入れ替えれば LEFT OUTER JOIN で書けるので、この教材では扱いません。
社員のいない部署を探す:IS NULL
外部結合でできた NULL は、第6章の IS NULL で探せます。「社員のいない部署」を取り出します。
SELECT d.DEPT_ID, d.DEPT_NAME
FROM DEPARTMENT d
LEFT OUTER JOIN EMPLOYEE e ON d.DEPT_ID = e.DEPT_ID
WHERE e.EMP_ID IS NULL;
| DEPT_ID | DEPT_NAME |
|---|---|
| 4 | 人事部 |
相手の社員がいない行だけ、社員側の EMP_ID が NULL になるので、それを条件にしています。この書き方は、「注文のない顧客」「売れていない商品」のように、相手がいないものを探すときの定番です。
NULL を別の値にする:NVL
NVL(値, 代わりの値) は、値が NULL のときだけ「代わりの値」を返す関数です。人事部の NAME を「(社員なし)」と表示します。
SELECT d.DEPT_NAME, NVL(e.NAME, '(社員なし)') AS NAME
FROM DEPARTMENT d
LEFT OUTER JOIN EMPLOYEE e ON d.DEPT_ID = e.DEPT_ID
ORDER BY d.DEPT_ID, e.EMP_ID;
| DEPT_NAME | NAME |
|---|---|
| 総務部 | 院照 心愛 |
| 総務部 | 鈴木 花子 |
| 営業部 | 雷禅 海皇 |
| 営業部 | 佐藤 健太 |
| 営業部 | 伊藤 さくら |
| 営業部 | 渡辺 大輔 |
| 開発部 | 林檎 星飛 |
| 開発部 | 田中 美咲 |
| 開発部 | 高橋 翔 |
| 開発部 | 中村 結衣 |
| 人事部 | (社員なし) |
NVL は、NULL が入り得る列を表示するときや、NULL のままだと計算結果が NULL になってしまうとき(NULL との足し算は NULL になります)に、0 や空の文字に置き換える目的でよく使います。
10.5 結合と集計を組み合わせる
第9章では、部署 ID ごとの人数しか求められず、社員のいない部署も表示されませんでした。結合を使えば、部署 名 で集計でき、外部結合なら人数 0 の部署も表示できます。
SELECT d.DEPT_NAME, COUNT(e.EMP_ID) AS CNT, ROUND(AVG(e.AGE), 1) AS AVG_AGE
FROM DEPARTMENT d
LEFT OUTER JOIN EMPLOYEE e ON d.DEPT_ID = e.DEPT_ID
GROUP BY d.DEPT_ID, d.DEPT_NAME
ORDER BY d.DEPT_ID;
| DEPT_NAME | CNT | AVG_AGE |
|---|---|---|
| 総務部 | 2 | 28 |
| 営業部 | 4 | 30.3 |
| 開発部 | 4 | 27.3 |
| 人事部 | 0 | (null) |
この SQL には、注意する点が2つあります。
-
COUNT(*)ではなくCOUNT(e.EMP_ID):人事部の行は、外部結合で1行(NAME などが NULL の行)として存在します。COUNT(*)はその行も数えるので、人事部が 1 になってしまいます。COUNT(e.EMP_ID)は NULL でない値だけを数えるので、正しく 0 になります(第9章) -
GROUP BY d.DEPT_ID, d.DEPT_NAME:ORDER BY d.DEPT_IDで部署IDの順に並べたいので、DEPT_ID も GROUP BY に入れています。GROUP BY に無い列は ORDER BY にも書けないためです。部署IDが同じなら部署名も同じなので、グループの分かれ方は変わりません
人事部の AVG_AGE は、年齢の値が1つも無いので NULL になります。
内部結合と HAVING を組み合わせて、「社員が4人以上いる部署の、部署名と人数と平均年齢」を求めます。
SELECT d.DEPT_NAME, COUNT(*) AS CNT, ROUND(AVG(e.AGE), 1) AS AVG_AGE
FROM EMPLOYEE e
INNER JOIN DEPARTMENT d ON e.DEPT_ID = d.DEPT_ID
GROUP BY d.DEPT_NAME
HAVING COUNT(*) >= 4
ORDER BY d.DEPT_NAME;
| DEPT_NAME | CNT | AVG_AGE |
|---|---|---|
| 営業部 | 4 | 30.3 |
| 開発部 | 4 | 27.3 |
最後に、WHERE も加えて「部署ごとの女性の人数を、多い順に」求めます。
SELECT d.DEPT_NAME, COUNT(*) AS CNT
FROM EMPLOYEE e
INNER JOIN DEPARTMENT d ON e.DEPT_ID = d.DEPT_ID
WHERE e.GENDER = 2
GROUP BY d.DEPT_NAME
ORDER BY CNT DESC, d.DEPT_NAME;
| DEPT_NAME | CNT |
|---|---|
| 総務部 | 2 |
| 開発部 | 2 |
| 営業部 | 1 |
結合・絞り込み・集計・並べ替えが1つの SELECT 文に入っています。読むときは、FROM・JOIN → WHERE → GROUP BY → HAVING → SELECT → ORDER BY の順に追うと、結果を予想できます。
10.6 うまくいかないときは
| 症状 | 考えられる原因と対処 |
|---|---|
| 「ORA-00918: 列の定義が未確定です。」 | 両方のテーブルにある列(DEPT_ID)を、別名なしで書いています。e.DEPT_ID のように別名を付けてください。 |
| 「ORA-00904: "E"."DEPT_NAME": 無効な識別子です。」 | 別名と列の組み合わせが違います。DEPT_NAME は部署テーブル(d)の列です。 |
| 「ORA-00905: キーワードがありません。」 |
ON と結合の条件が抜けています。 |
| 「ORA-00933: SQLコマンドが正しく終了されていません。」 | テーブルの別名に AS を付けています(EMPLOYEE AS e)。テーブルの別名は EMPLOYEE e と書きます。句の順番が違うときにも出ます。 |
| 結果の行数が、社員の数より多い | 結合の条件(ON)が間違っているか抜けています。条件が無いと、全社員 × 全部署(10 × 4 = 40 行)の組み合わせがすべて返されます。 |
| 社員のいない部署が出てこない |
INNER JOIN を使っています。LEFT OUTER JOIN にして、部署テーブルを FROM(左)に書いてください。 |
| 人数 0 の部署が 1 と数えられる |
COUNT(*) を使っています。COUNT(e.EMP_ID) にしてください。 |
ほかのエラーは、付録B「よくあるエラーと対処法」 も参考にしてください。
10.7 まとめと確認問題
まとめ
- 結合は、2つのテーブルを共通の列の値でつなげて1つの表にする。
FROM テーブル1 別名1 INNER JOIN テーブル2 別名2 ON 結合の条件 - テーブルには別名を付け、列は
別名.列名で書く。テーブルの別名にASは書けない -
INNER JOINは両方に相手がいる行だけを残す。LEFT OUTER JOINは左のテーブルの全行を残し、相手がいない行の右の列は NULL になる - 外部結合でできた NULL は
IS NULLで探せ、NVLで別の値に置き換えられる - 結合した結果に WHERE・GROUP BY・HAVING・ORDER BY を組み合わせられる。人数 0 を正しく数えるには
COUNT(列名)を使う
この章で使った SQL は、付録C「SQL 早見表」 にまとめています。
確認問題
問1 FROM EMPLOYEE e INNER JOIN DEPARTMENT d ON e.DEPT_ID = d.DEPT_ID の ON に書いているのは、何と何を結ぶ条件ですか。
解答を見る
社員テーブルの外部キー DEPT_ID と、それが参照する部署テーブルの主キー DEPT_ID です。この2つの値が同じ行同士をつなげます。
問2 営業部の社員の氏名と年齢を、部署名を条件にして取り出す SQL を書いてください。
解答を見る
SELECT e.NAME, e.AGE FROM EMPLOYEE e INNER JOIN DEPARTMENT d ON e.DEPT_ID = d.DEPT_ID WHERE d.DEPT_NAME = '営業部';
結果は 雷禅・佐藤・伊藤・渡辺 の4行です。
問3 部署テーブルを左にした INNER JOIN と LEFT OUTER JOIN で、結果の行数が違うのはなぜですか。
解答を見る
人事部には社員がいないためです。INNER JOIN は相手のいる行だけを残すので10行、LEFT OUTER JOIN は左の部署テーブルの全行を残すので、人事部の行(社員側の列は NULL)が加わって11行になります。
問4 部署ごとの人数を求めるとき、COUNT(*) ではなく COUNT(e.EMP_ID) を使うのはどんな場合ですか。
解答を見る
外部結合で、社員のいない部署も表示する場合です。COUNT(*) は NULL だけの行も1と数えてしまいますが、COUNT(e.EMP_ID) は NULL でない値だけを数えるので、正しく 0 になります。
問5 SELECT DEPT_ID, NAME FROM EMPLOYEE e INNER JOIN DEPARTMENT d ON e.DEPT_ID = d.DEPT_ID; がエラーになる理由と、直し方を答えてください。
解答を見る
DEPT_ID が両方のテーブルにあり、どちらの列か決まらないためです(ORA-00918)。SELECT e.DEPT_ID, e.NAME のように別名を付けます。
10.8 この教材のまとめと次のステップ
学んだこと
この教材では、Oracle Database と SQL Developer を使って、次のことを学びました。
| 章 | 学んだこと | 主な SQL |
|---|---|---|
| 第1章 | データベース、テーブル・行・列、主キーと外部キー、SQL の種類 | — |
| 「開発環境の準備」・第2章 | Oracle XE と SQL Developer の準備、接続、ユーザーの作成 |
CREATE USER・GRANT
|
| 第3章 | テーブルの作成、データ型、制約、シーケンス |
CREATE TABLE・CREATE SEQUENCE・DROP TABLE
|
| 第4章 | データの登録、確定と取り消し |
INSERT・COMMIT・ROLLBACK
|
| 第5章・第6章 | データの取り出し、並べ替え、条件での絞り込み |
SELECT・ORDER BY・WHERE
|
| 第7章 | データの変更と削除 |
UPDATE・DELETE
|
| 第8章・第9章 | 関数、集計 |
TO_CHAR など・GROUP BY・HAVING
|
| 第10章 | 結合 |
INNER JOIN・LEFT OUTER JOIN
|
登録(INSERT)・取り出し(SELECT)・変更(UPDATE)・削除(DELETE)の4つ(CRUD)と、絞り込み・集計・結合が書ければ、業務のシステムで使われる SQL の大部分を読み書きできます。この教材で扱わなかったもの(副問合せ、ビュー、インデックス、テーブルの定義変更など)は、この土台の上に積み上げるものです。必要になったときに、Oracle のマニュアルや書籍で調べられます。
Spring入門へ進む
Spring入門 では、この教材と同じ部署テーブル・社員テーブルを使って、Java と Spring Boot で社員管理の Web アプリケーションを作ります。アプリが行うのは、この教材で学んだ SQL そのものです。
| アプリの機能 | この教材で学んだ SQL |
|---|---|
| 社員一覧画面(部署名付き) |
SELECT … FROM EMPLOYEE e INNER JOIN DEPARTMENT d ON …(10.2) |
| 社員の新規登録 |
INSERT INTO EMPLOYEE … VALUES (SEQ_EMP.NEXTVAL, …)(第4章) |
| 社員の変更 |
UPDATE EMPLOYEE SET … WHERE EMP_ID = ?(第7章) |
| 社員の削除 |
DELETE FROM EMPLOYEE WHERE EMP_ID = ?(第7章) |
Spring入門では、これらの SQL を自分で書く代わりに、JPA という仕組みが Java のコードから SQL を組み立てて実行します。しかし、裏で動いている SQL が分かっていれば、アプリの動きが理解しやすく、うまく動かないときの原因も探しやすくなります。
【知識メモ】Spring入門のテーブルとの違い
Spring入門の第3章では、アプリ専用のユーザー empapp を作り、この教材と同じ部署テーブル・社員テーブルを作り直します。ただし、Spring入門のテーブルには、この教材で学習のために付けた GENDER の CHECK 制約はありません。また、サンプルデータは社員3人(雷禅・院照・林檎)だけです。この教材の dbapp のテーブルはそのまま残しておいてかまいません。スキーマが違うので、Spring入門の empapp のテーブルとは別のものとして共存できます。
この教材で作った dbapp のテーブルは、SQL の練習用にいつでも使えます。Spring入門を進めながら、アプリが行っている操作を SQL Developer で試してみると、理解が深まります。
