1

従業員、その仕事、給与、プロジェクトの情報を含むデータベースを作成したい

プロジェクトのコスト(プロジェクトの実際の価値と従業員が投資した日数)の情報を保持したい

従業員とプロジェクトの場合、各従業員はPK制約を介してプロジェクトで1つの役割を持ち、将来、新しい役割タイプ(おそらく「第3」)を追加できます。

    CREATE TABLE Employee(
      EmployeeID  INTEGER      NOT NULL PRIMARY KEY,
      Name        VARCHAR(30)  NOT NULL,
      Sex         CHAR(1)      NOT NULL,
      Address     VARCHAR(80)  NOT NULL,
      Security    VARCHAR(15)  NOT NULL,
      DeptID      INTEGER      NOT NULL,        
      JobID       INTEGER      NOT NULL
    );

    CREATE TABLE Departments  (
        DeptID   INTEGER     NOT NULL PRIMARY KEY,
        DeptName VARCHAR(30) NOT NULL
    );

    CREATE TABLE Jobs (
        JobID            INTEGER      NOT NULL PRIMARY KEY,
        JobName          VARCHAR(30)  NOT NULL,
        JobSalary        DOUBLE(15,3) NOT NULL default '0.000', 
        JobSalaryperDay  DOUBLE(15,3) NOT NULL default '0.000', 
        DeptID           INTEGER      NOT NULL
    );


    CREATE TABLE Project(
      ProjectID    INTEGER NOT NULL PRIMARY KEY,
      ProjectDesc   VARCHAR(200) NOT NULL,
      StartDate     DATE NOT NULL,
      EndDate       DATE NOT NULL, 
      DaysOfWork    INTEGER NOT NULL,
      NoEmployees   INTEGER NOT NULL,
      EstimatedCost DOUBLE(15,3) NOT NULL default '0.000', 
      RealCost      DOUBLE(15,3) NOT NULL default '0.000' 
    );


    CREATE TABLE `Project-Employee`(
      ProjectID    INTEGER NOT NULL,
      EmployeeID   INTEGER NOT NULL,
      Note         VARCHAR(200),
      DaysWork     INTEGER NOT NULL,
      CONSTRAINT fk_ProjectID  FOREIGN KEY (ProjectID)  REFERENCES Project(ProjectID),
      CONSTRAINT fk_EmployeeID FOREIGN KEY (EmployeeID) REFERENCES Employee(EmployeeID)
    );


INSERT INTO `Departments` VALUES (1, 'Outsourcing');
INSERT INTO `Departments` VALUES (2, 'Technician');
INSERT INTO `Departments` VALUES (3, 'Administrative');

INSERT INTO `Jobs` VALUES (1, 'welder'    ,500.550,16.7 ,2);
INSERT INTO `Jobs` VALUES (2, 'turner'    ,500.100,16.67,2);
INSERT INTO `Jobs` VALUES (3, 'assistant' ,650.100,21.67,2);
INSERT INTO `Jobs` VALUES (4, 'supervisor',800.909,26.70,3);
INSERT INTO `Jobs` VALUES (5, 'manager'   ,920.345,30.68,3);
INSERT INTO `Jobs` VALUES (6, 'counter'   ,520.324,17.35,1);



INSERT INTO `Employee` VALUES (10, 'Joe',  'M', 'Anywhere', '927318344', 1, 3);
INSERT INTO `Employee` VALUES (20, 'Moe',  'M', 'Anywhere', '827318322', 2, 3);
INSERT INTO `Employee` VALUES (30, 'Jack', 'M', 'Anywhere', '927418343', 3, 4);
INSERT INTO `Employee` VALUES (40, 'Marge','F', 'Evererre', '127347645', 1, 6);
INSERT INTO `Employee` VALUES (50, 'Greg' ,'M', 'Portland', '134547633', 3, 5);


INSERT INTO `Project` VALUES (1, 'The very first', '2008-7-04' , '2008-7-24' , 20, 5, 3000.50, 2500.00);
INSERT INTO `Project` VALUES (2, 'Second one pro', '2008-8-01' , '2008-8-30' , 30, 5, 6000.40, 6100.40);


INSERT INTO `Project-Employee` VALUES (1, 10, 'Worked all days'    , 20);
INSERT INTO `Project-Employee` VALUES (1, 20, 'Worked just in defs', 11);
INSERT INTO `Project-Employee` VALUES (1, 30, 'Worked just in defs', 17);
INSERT INTO `Project-Employee` VALUES (1, 40, 'Contability '       , 8);
INSERT INTO `Project-Employee` VALUES (1, 50, 'Managed the project', 8);

したがって、プロジェクトのコストの合計額を取得し、将来の作業見積もりに使用するには、集計クエリで各従業員の各ジョブの稼働日数を合計します。

特定のプロジェクトに関与する従業員を知っているすべての営業日を合計して、彼らの仕事にかかるコストを知るためのクエリは何でしょうか。この設計でこれを知ることは可能ですか?

したがって、プロジェクト1には、5人の従業員が関与しており、他のテーブルの「仕事」によって、1日あたりの給与を1人ずつ支払うことを知っているとします。

私はここでsqlfiddleを使っていくつかのクエリを行っています

アップデート

 CREATE TABLE `Sexes` (
   Sex char(1) primary key
 );
 INSERT INTO Sexes values ('M');
 INSERT INTO Sexes values ('F');

CREATE TABLE `Employee`(
  EmployeeID  INTEGER      NOT NULL PRIMARY KEY,
  Name        VARCHAR(130)  NOT NULL,
  Sex         CHAR(1)      NOT NULL,
  Address     VARCHAR(380)  NOT NULL,
  Security    VARCHAR(15)  NOT NULL,
  FOREIGN KEY (Sex) references Sexes (Sex),
  CONSTRAINT `uc_EmployeeInfo` UNIQUE (`EmployeeID`,`Name`,`Security`)           
);

CREATE TABLE `Department`  (
  DeptID   INTEGER     NOT NULL PRIMARY KEY,
  DeptName VARCHAR(30) NOT NULL,
  CONSTRAINT `uc_DeptName` UNIQUE (`DeptID`,`DeptName`)
);

CREATE TABLE `Dept-Employee`(
  EmployeeID   INTEGER NOT NULL,          
  DeptID       INTEGER NOT NULL,     
  CONSTRAINT fk_DeptID     FOREIGN KEY (DeptID)     REFERENCES `Department`(DeptID),
  CONSTRAINT fk_EmployeeID FOREIGN KEY (EmployeeID) REFERENCES `Employee`(EmployeeID)
);

 CREATE TABLE `Dept-Manager`(
  EmployeeID   INTEGER NOT NULL,          
  DeptID       INTEGER NOT NULL,
  CONSTRAINT fk_DeptIDs     FOREIGN KEY (DeptID)     REFERENCES `Department`(DeptID),
  CONSTRAINT fk_EmployeeIDs FOREIGN KEY (EmployeeID) REFERENCES `Employee`(EmployeeID)
);

CREATE TABLE `Jobs` (
  JobID            INTEGER      NOT NULL PRIMARY KEY,
  JobName          VARCHAR(30)  NOT NULL,
  JobSalary        DECIMAL(7,3) NOT NULL default '0000.000', 
  JobSalaryperDay  DECIMAL(7,3) NOT NULL default '0000.000', 
  CONSTRAINT `uc_jobs` UNIQUE (`JobID`,`JobName`)
);

CREATE TABLE `Jobs-Employee`(
  EmployeeID   INTEGER NOT NULL,
  JobID        INTEGER NOT NULL,
  CONSTRAINT fk_JobIDs       FOREIGN KEY (JobID)      REFERENCES `Jobs`(JobID),
  CONSTRAINT fk_EmployeeIDss FOREIGN KEY (EmployeeID) REFERENCES `Employee`(EmployeeID)
);

CREATE TABLE `Project`(
  ProjectID     INTEGER NOT NULL PRIMARY KEY,
  ProjectName   VARCHAR(200) NOT NULL,
  StartDate     DATE    NOT NULL,
  DaysOfWork    INTEGER NOT NULL,
  NoEmployees   INTEGER NOT NULL,
  EstimatedCost DECIMAL(9,3) NOT NULL default '000000.000', 
  RealCost      DECIMAL(9,3) NOT NULL default '000000.000', 
  CONSTRAINT `uc_project` UNIQUE (`ProjectID`,`ProjectName`)           
);

CREATE TABLE `Project-Employee`(
  ProjectID    INTEGER NOT NULL,
  EmployeeID   INTEGER NOT NULL,
  Note         VARCHAR(200),
  DaysWork     INTEGER NOT NULL,
  CONSTRAINT fk_ProjectIDsss  FOREIGN KEY (ProjectID)  REFERENCES `Project`(ProjectID),
  CONSTRAINT fk_EmployeeIDsss FOREIGN KEY (EmployeeID) REFERENCES `Employee`(EmployeeID)
);


    INSERT INTO `Department` VALUES (1, 'Outsourcing');
    INSERT INTO `Department` VALUES (2, 'Technician');
    INSERT INTO `Department` VALUES (3, 'Administrative');

    INSERT INTO `Jobs` VALUES (1, 'welder'    ,500.550, 16.7 );
    INSERT INTO `Jobs` VALUES (2, 'turner'    ,500.100, 16.67);
    INSERT INTO `Jobs` VALUES (3, 'assistant' ,650.100, 21.67);
    INSERT INTO `Jobs` VALUES (4, 'supervisor',800.909, 26.70);
    INSERT INTO `Jobs` VALUES (5, 'manager'   ,920.345, 30.68);
    INSERT INTO `Jobs` VALUES (6, 'counter'   ,520.324, 17.35);

    INSERT INTO `Employee` VALUES (10, 'Joe',  'M', 'Joewhere', '927318344');
    INSERT INTO `Employee` VALUES (20, 'Moe',  'M', 'Moewhere', '827318322');
    INSERT INTO `Employee` VALUES (30, 'Jack', 'M', 'Jaswhere', '927418343');
    INSERT INTO `Employee` VALUES (40, 'Marge','F', 'Evererre', '127347645');
    INSERT INTO `Employee` VALUES (50, 'Greg' ,'M', 'Portland', '134547633');

    INSERT INTO `Dept-Employee`  VALUES (10,1);
    INSERT INTO `Dept-Employee`  VALUES (20,2);
    INSERT INTO `Dept-Employee`  VALUES (30,3);
    INSERT INTO `Dept-Employee`  VALUES (40,1);
    INSERT INTO `Dept-Employee`  VALUES (50,3);

    INSERT INTO `Jobs-Employee`  VALUES (10,3);
    INSERT INTO `Jobs-Employee`  VALUES (20,3);
    INSERT INTO `Jobs-Employee`  VALUES (30,4);
    INSERT INTO `Jobs-Employee`  VALUES (40,6);
    INSERT INTO `Jobs-Employee`  VALUES (50,5);

    INSERT INTO `Project` VALUES (1, 'The very first', '2008-7-04' , 20, 5, 3000.50, 2500.00);
    INSERT INTO `Project` VALUES (2, 'Second one pro', '2008-8-01' , 30, 5, 6000.40, 6100.40);

    INSERT INTO `Project-Employee` VALUES (1, 10, 'Worked all days'    , 20);
    INSERT INTO `Project-Employee` VALUES (1, 20, 'Worked just in defs', 11);
    INSERT INTO `Project-Employee` VALUES (1, 30, 'Worked just in defs', 17);
    INSERT INTO `Project-Employee` VALUES (1, 40, 'Contability '       , 8);
    INSERT INTO `Project-Employee` VALUES (1, 50, 'Managed the project', 8);

新しい構造に私はこれをしました

CREATE VIEW `Emp-Job` as
SELECT e.*,j.jobID  
FROM  Employee e,`Jobs-Employee` j
WHERE e.EmployeeID = j.EmployeeID;



CREATE VIEW `employee_pay` as
select e.*, j.jobname, j.jobsalary, j.jobsalaryperday
from `Emp-Job` e
inner join `Jobs` j
        on e.JobID = j.JobID;

create view project_pay as 
select pe.projectid, pe.employeeid, pe.dayswork,
       e.jobsalaryperday, (e.jobsalaryperday * dayswork) as total_salary
from `Project-Employee` pe
inner join `employee_pay` e
        on e.employeeid = pe.employeeid
4

1 に答える 1

2

質問の最後のデータがINSERTステートメントのデータと一致していないようです。

「分割統治」について聞いたことがありますか?これはそれを使用する良い時期です。これが私がすることです。

create view employee_pay as
select e.*, j.jobname, j.jobsalary, j.jobsalaryperday
from employee e
inner join jobs j on e.jobid = j.jobid

create view project_pay as 
select pe.projectid, pe.employeeid, pe.dayswork,
       e.jobsalaryperday, (e.jobsalaryperday * dayswork) as total_salary
from project_employee pe
inner join employee_pay e
        on e.employeeid = pe.employeeid

これらのビューは一般的に役立つと思うので、そうします。(特にデバッグ用です。)これらのビューを作成すると、プロジェクトの合計は非常に単純になります。

select projectid, sum(total_salary) as total_salaries
from project_pay
group by projectid

projectid  total_salaries
--
1          1509.91

あなたは本当にお金のためにDOUBLEを使いたくありません。代わりにDECIMALを使用してください


このクエリを使用して、私の合計があなたの合計と一致しない理由を整理します。

select p.*, e.name
from project_pay p
inner join employee e on e.employeeid = p.employeeid;

projectid  employeeid  dayswork  jobsalaryperday  total_salary  name
1          10          20        21.67            433.4         Joe
1          20          11        21.67            238.37        Moe
1          30          17        26.7             453.9         Jack
1          40           8        17.35            138.8         Marge
1          50           8        30.68            245.44        Greg

アンチパターン

壊れたアイデンティティ

このようなテーブルを見るときはいつでも

CREATE TABLE Departments  (
    DeptID   INTEGER     NOT NULL PRIMARY KEY,
    DeptName VARCHAR(30) NOT NULL
);

その構造が間違っていると想定し、深く掘り下げる必要があります。(無罪が証明されるまでは有罪と推定されます。)あなたが探しているアンチパターン

  • 人工主キーとしての整数と
  • 他に固有の制約はありません。

このようなテーブルを使用すると、実際のデータを複製できるため、人工的なキーの有用性がなくなります。

DeptID  DeptName
--
1       Wibble
2       Wibble
...
175     Wibble

このようなテーブルでは、複数の外部キー参照も可能になります。つまり、一部の外部キーはWibble(DeptID = 1)を参照し、一部はWibble(DeptID = 175)を参照する可能性があります。

これを修正するには、DeptNameにUNIQUE制約を追加します。

外部キー参照がありません

このようなテーブルを見るときはいつでも

CREATE TABLE Employee(
  EmployeeID  INTEGER      NOT NULL PRIMARY KEY,
  Name        VARCHAR(30)  NOT NULL,
  ...
  DeptID      INTEGER      NOT NULL,        
  JobID       INTEGER      NOT NULL
);

その構造が間違っていると想定し、深く掘り下げる必要があります。(繰り返しますが、無罪が証明されるまでは有罪と推定されます。)あなたが探しているアンチパターン

  • 他のテーブルのID番号と
  • これらのテーブルを参照する外部キー制約はありません。

これを修正するには、DeptIDとJobIDに外部キー制約を追加します。MySQLでは、INNODBエンジンも使用していることを確認してください。(MySQL 5.6の時点では、MyISAMは外部キー制約を適用しませんが、それらを記述してもエラーや警告は表示されません。それらは解析され、無視されます。)

別のデータベース管理システムからMySQLにアクセスした場合、MySQLがインライン外部キー参照構文をサポートしていないことに驚かれることでしょう。それはあなたがこれを書くことができないことを意味します。

DeptID integer not null references Departments (DeptID)

代わりに、CREATETABLEステートメントに別の外部キー句を記述する必要があります。(または、別のALTER TABLEステートメントを使用してFK参照を宣言します。)

DeptID integer not null,
foreign key (DeptID) references Departments (DeptID)

このページで「インライン参照」を検索してください。ただし、すべてを読んでください。

CHECK()制約がありません

MySQLはCHECK()制約を強制しないため、CHECK()制約を要求する列には、テーブルと外部キー参照が必要です。このような構造を見ると

CREATE TABLE Employee(
  EmployeeID  INTEGER      NOT NULL PRIMARY KEY,
  Name        VARCHAR(30)  NOT NULL,
  Sex         CHAR(1)      NOT NULL,

列「Sex」はCHECK()制約を要求します。

CREATE TABLE Employee(
  EmployeeID  INTEGER      NOT NULL PRIMARY KEY,
  Name        VARCHAR(30)  NOT NULL,
  Sex         CHAR(1)      NOT NULL CHECK( Sex IN ('M', 'F')),

ただし、MySQLはCHECK()制約を強制しないため、別のテーブルと外部キー参照が必要です。

create table sexes (
  sex char(1) primary key
);
insert into sexes values ('M');
insert into sexes values ('F');

CREATE TABLE Employee(
  EmployeeID  INTEGER      NOT NULL PRIMARY KEY,
  Name        VARCHAR(30)  NOT NULL,
  Sex         CHAR(1)      NOT NULL,
  ...
  foreign key (Sex) references Sexes (Sex)

これらの列のほとんどについて、CHECK()制約を検討します。一部は、外部キー参照を持つテーブルとして実装できます。

  • Employee.Security
  • Jobs.JobSalary
  • Jobs.JobSalaryperDay
  • Project.DaysOfWork
  • Project.NoEmployees
  • Project.EstimatedCost
  • Project.RealCost
  • Project_Employee.DaysWork

お金のために浮動小数点データ型を使用する

そうしないでください。浮動小数点数は有用な近似値ですが、それでも近似値です。代わりにDECIMALを使用してください。

于 2012-11-07T01:43:08.700 に答える