これは宿題なので、適切な方法で表を設計する方法について意見を述べたいと思います。ちょうど私の2セント。
デザイン提案
テーブルのデザインを変更することをお勧めします。すべてのテーブルには、基本的に同じデータが含まれています。
複数のテーブルを持つ代わりに、2 つのテーブルのみを含むように、この方針に沿ってデータベースを設計する必要があります。
Department
----------
dept_no INTEGER
dept_name VARCHAR(30)
Person
------
person_no INTEGER
person_name VARCHAR(30)
dept_no INTEGER
制約付きのテーブルを作成する
適切な制約を使用してテーブルを設計する必要があります。ここで注意すべき点がいくつかあります。
名前が示すように、制約PRIMARY KEY
はテーブルに主キーを作成してデータを一意に保ち、同じ値を持つ複数の ID が作成されないようにします。
制約FOREIGN KEY
は、テーブル Department と Person の間の関係を作成しています。
この例では、これらのキーは必要ないかもしれませんが、実際のアプリケーションでは、外部キー制約を使用して適切な関係を定義することが常にベスト プラクティスです。PRIMARY KEY
Web 上で検索できるものは他にもたくさんありますFOREIGN KEY
。
これらのテーブルが作成される順序を切り替えることはできません。つまり、最初に Person テーブルを作成してから Department テーブルを作成することはできません。その理由は、Person テーブルが Department テーブルを参照する制約を作成しているためです。最初に Person テーブルを作成すると、エラーが発生しますFailed: ORA-00942: table or view does not exist
。
dept_no
とを自動インクリメントする数値にすることもできるperson_no
ので、これらの数値を手動で挿入する必要はありません。SQL Server を使用しています。そのため、列を自動インクリメント番号にするためのOracle構文にはあまり詳しくありません。Oracle のシーケンス番号を検索すると、何かが見つかるかもしれません。
スクリプト:
CREATE TABLE Department
(
dept_no INTEGER
, dept_name VARCHAR(30)
, CONSTRAINT pk_department PRIMARY KEY (dept_no)
);
CREATE TABLE Person
(
person_no INTEGER
, person_name VARCHAR(30)
, dept_no INTEGER
, CONSTRAINT pk_person PRIMARY KEY (person_no)
, CONSTRAINT fk_person_dept FOREIGN KEY (dept_no)
REFERENCES Department (dept_no)
);
テーブルにデータを入力する
以下のスクリプトは、最初に Department テーブルにデータを入力し、次に Person テーブルにデータを入力します。
実際には、行ごとに INSERT INTO を呼び出すのではなく、複数の値を同時にテーブルに挿入しています。
dualは、単一行の Oracle のダミー テーブルです。デュアルに関するこのSOの回答をここで読んでください。
スクリプト:
INSERT ALL
INTO Department (dept_no, dept_name) VALUES (1, 'Cleaner')
INTO Department (dept_no, dept_name) VALUES (2, 'Driver')
INTO Department (dept_no, dept_name) VALUES (3, 'Mechanic')
SELECT * FROM dual;
INSERT ALL
INTO Person (person_no, person_name, dept_no) VALUES (1, 'Cleaner 1', 1)
INTO Person (person_no, person_name, dept_no) VALUES (2, 'Cleaner 2', 1)
INTO Person (person_no, person_name, dept_no) VALUES (3, 'Cleaner 3', 1)
INTO Person (person_no, person_name, dept_no) VALUES (4, 'Cleaner 4', 1)
INTO Person (person_no, person_name, dept_no) VALUES (5, 'Driver 1', 2)
INTO Person (person_no, person_name, dept_no) VALUES (6, 'Driver 2', 2)
INTO Person (person_no, person_name, dept_no) VALUES (7, 'Driver 3', 2)
INTO Person (person_no, person_name, dept_no) VALUES (8, 'Mechanic 1', 3)
INTO Person (person_no, person_name, dept_no) VALUES (9, 'Mechanic 2', 3)
INTO Person (person_no, person_name, dept_no) VALUES (10, 'Mechanic 3', 3)
INTO Person (person_no, person_name, dept_no) VALUES (11, 'Mechanic 4', 3)
INTO Person (person_no, person_name, dept_no) VALUES (12, 'Mechanic 5', 3)
INTO Person (person_no, person_name, dept_no) VALUES (13, 'Mechanic 6', 3)
SELECT * FROM dual;
部門ごとにグループ化されたデータを取得するにはどうすればよいですか?
テーブルとデータが用意できたので、情報をクエリします。
要件は、すべての部門のリストと各部門の人数を取得することです。
次のクエリを実行すると、単に部門のリストが取得されますが、それは必要なものではありません。
シンプルセレクト:
SELECT dept_no
, dept_name
FROM Department;
出力:
DEPT_NO DEPT_NAME
------- ---------
1 Cleaner
2 Driver
3 Mechanic
- そのため、「どうすればその情報を入手できますか?」と尋ねるかもしれません。'。さて、その情報はテーブル Person にあります。したがって、目的のデータを見つけるには、両方のテーブルを結合する必要があります。
INNER JOIN
共通のフィールドで両方のテーブルを結合するために使用します。この場合、両方のテーブルの共通フィールドはdept_noです。
目的の出力が得られるクエリ
スクリプト:
SELECT d.dept_no
, d.dept_name
, COUNT(p.person_no) AS No_of_employees
FROM Department d
INNER JOIN Person p
ON p.dept_no = d.dept_no
GROUP BY d.dept_no
, d.dept_name
ORDER BY d.dept_no;
出力:
DEPT_NO DEPT_NAME NO_OF_EMPLOYEES
------- --------- ---------------
1 Cleaner 4
2 Driver 3
3 Mechanic 6
説明
クエリでは、INNER JOIN、GROUP BY、COUNT、ORDER BY など、さまざまなものが使用されます。これらをそれぞれ見ていきましょう。
INNER JOINは、共通フィールド (この場合は dept_no) に基づいてテーブルを結合します。
COUNT関数を使用すると、クエリですべての従業員数を部署名と部署名でグループ化できます。
COUNT
集計関数です。非集計列で集計関数を使用する場合は、GROUP BY 句を使用する必要があります。ここで、dept_no と dept_name は非集計列です。SUM
、MAX
。MIN
集計関数の一部です。
最後に、ORDER BY句を適用して、出力をdept_no列でソートします。
デモ
SQL Fiddle でデモを表示するには、ここをクリックしてください。