web-dev-qa-db-ja.com

多対多の関係のマッピング

2つのテーブルがあります。

  1. 列employee_id(主キー)とemployee_nameを持つ従業員表。
  2. 列company_id(主キー)とcompany_nameを持つCompanyテーブル。

会社はその従業員が他の会社のために働くことを許可します。したがって、従業員は多くの会社で働くことができ、会社は多くの従業員を持つことができます(多対多の関係)。

たとえば、3人の従業員とその従業員が1日の開始時間と終了時間を担当しているとします。

employee_name | company_name | hours they work |
Akash            A               09:00 - 11:00                            
                 B               12:00 - 02:00                       
                 C               04:00 - 07:00  

Sunny            D               09:00 - 11:00
                 C               12:00-  04:00
                 D               05:00 - 07:00 

Vishal           B               09:00 - 12:00 
                 A               12:00 - 05:00
  • データベースはどのように設計すればよいですか?
  • 特定の会社で最も長時間働いた従業員を見つけるにはどうすればよいですか?
8
user4946127

従業員と会社の情報を格納するために、従業員テーブルと会社テーブルの両方があります。ただし、多対多の関係であるため、この関係には別のテーブルが必要です。

ここでも、勤務時間情報は関係属性です。従業員が会社で働き始めるまで存在しません。

ERダイアグラムは次のようになります。 er diagram

このリレーションをマップすると、company_employee(employee_id、company_id、work_hours)というテーブルができます。

テーブルのSQLコード:

CREATE TABLE employee (
    employee_id INTEGER PRIMARY KEY,
    employee_name VARCHAR(100) NOT NULL
);

CREATE TABLE company (
    company_id INTEGER PRIMARY KEY,
    company_name VARCHAR(300) NOT NULL
);

CREATE TABLE company_employee (
    employee_id INTEGER NOT NULL,
    company_id INTEGER NOT NULL,
    work_hour_start TIME NOT NULL,
    work_hour_end TIME NOT NULL,
    FOREIGN KEY (employee_id) REFERENCES employee (employee_id) ON DELETE RESTRICT ON UPDATE CASCADE,
    FOREIGN KEY (company_id) REFERENCES company (company_id) ON DELETE RESTRICT ON UPDATE CASCADE,
    PRIMARY KEY (employee_id, company_id, work_hour_start, work_hour_end)
);

Company_employeeテーブルでは、必要に応じて、勤務時間を1つの列に格納することもできます。

列を表示するには、

SELECT e.employee_name, c.company_name, ec.work_hour_start, ec.work_hour_end
FROM employee e
INNER JOIN company_employee ec
ON e.employee_id = ec.employee_id
INNER JOIN company c
ON c.company_id = ec.company_id;

最後に、これは誰がどの会社で何時間働いたかを示します。

SELECT c.company_name, e.employee_name, MAX(ec.work_hour_end - ec.work_hour_start) AS max_hours
FROM employee e
INNER JOIN company_employee ec
ON e.employee_id = ec.employee_id
INNER JOIN company c
ON c.company_id = ec.company_id
GROUP BY c.company_name, e.employee_name
ORDER BY c.company_name;
13
ukll