我想创建一个包含员工,工作,工资和项目信息的数据库
我想保留项目成本的信息(项目的实际价值和员工投资的天数)
对于员工和项目,每个员工通过PK约束在项目中有一个角色,并允许在将来添加新的角色类型(可能是“第三个”)。
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名员工参与其中,而我从其他表“工作”中知道我每天要支付的工资
我正在进行一些查询here with 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
答案 0 :(得分: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赚钱。 Use DECIMAL instead
使用此查询来理清我的总和与您的总和不匹配的原因。
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
);
你应该假设它的结构是错误的,并深入挖掘。 (再一次,在被证明是无辜之前,它被认为是有罪的。)你寻找的反模式
要解决此问题,请为DeptID和JobID添加外键约束。在MySQL上,确保你也使用INNODB引擎。 (从MySQL 5.6开始,MyISAM still won't enforce foreign key constraints,但如果你编写它们就不会给你一个错误或警告。它们被解析并被忽略。)
如果你从另一个dbms来到MySQL,你会惊讶地发现MySQL不支持内联外键引用语法。这意味着你不能写这个。
DeptID integer not null references Departments (DeptID)
相反,您必须在CREATE TABLE语句中编写单独的外键子句。 (或使用单独的ALTER TABLE语句声明FK引用。)
DeptID integer not null,
foreign key (DeptID) references Departments (DeptID)
在this page搜索“inline ref”,但请阅读整篇文章。
MySQL不强制执行CHECK()约束,因此对于请求CHECK()约束的列,您需要一个表和一个外键引用。当你看到像这样的结构时
CREATE TABLE Employee(
EmployeeID INTEGER NOT NULL PRIMARY KEY,
Name VARCHAR(30) NOT NULL,
Sex CHAR(1) NOT NULL,
CHOOK()约束中的“Sex”列。
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()约束。有些可以实现为具有外键引用的表。
不要那样做。浮点数是有用的近似值,但它们仍然是近似值。请改用DECIMAL。