员工详细信息及其工作类型

时间:2015-05-31 07:29:18

标签: mysql sql

我有一个包含以下表格的数据库:

 create table EMPLOYEE
 (
   Emp_ID INT NOT NULL AUTO_INCREMENT,
   Emp_FName VARCHAR(30) NOT NULL,
   Emp_LName VARCHAR(30) NOT NULL,
   Address_ID_Resident INT REFERENCES ADDRESS(Address_ID),
   JobTime_ID CHAR(1) REFERENCES JOBTIME(JobTime_ID),
   PRIMARY KEY(Emp_ID)
 );

其他表格地址如下:

 create table ADDRESS
 (
    Address_ID INT NOT NULL AUTO_INCREMENT,
    Address_St VARCHAR(50) NOT NULL,
    Address_City VARCHAR(30) NOT NULL,
    Address_State VARCHAR(3) NOT NULL,
    Address_PostCode CHAR(4) NOT NULL,
    Add_TypeID CHAR(1) REFERENCES ADDRESSTYPE(Add_TypeID),
    PRIMARY KEY(Address_ID)
 );

ADDRESSTYPE表是告知地址是住宅,办公室,邮政

create table ADDRESSTYPE
(
  AddType_ID CHAR(1) NOT NULL,
  Add_Type VARCHAR(15) NOT NULL,
  PRIMARY KEY(AddType_ID)
);

JobTime Table描述员工的工作是全职还是休闲。

Create table JOBTIME
(
  JobTime_ID CHAR(1) NOT NULL,
  JobTime_Desc VARCHAR(10) NOT NULL,
  PRIMARY KEY(JobTime_ID)
);

现在他们每个人都有不同的薪水所以对于全职和休闲,我们有两个单独的表。

 Create table FULLTIME
 (
   Emp_ID INT NOT NULL,
   Emp_salary_yearly DOUBLE(10,2) NOT NULL,
   JobType_ID INT REFERENCES JOBTYPE(JobType_ID),
   FullTimeJob_ID CHAR(1) NOT NULL DEFAULT 'F',
   PRIMARY KEY(Emp_ID)
  );

  ALTER TABLE FULLTIME ADD FOREIGN KEY(Emp_ID) REFERENCES EMPLOYEE(Emp_ID);

  ALTER TABLE FULLTIME ADD FOREIGN KEY(FullTimeJob_ID) REFERENCES JOBFULLTIME(FullTimeJob_ID);

 Create table CASUALTIME
 (
   Emp_ID INT NOT NULL,
   Emp_salary_hourly DOUBLE(10,2) NOT NULL,
   JobType_ID INT REFERENCES JOBTYPE(JobType_ID),
   CasualJob_ID CHAR(1) NOT NULL DEFAULT 'C',
   PRIMARY KEY(EMP_ID)
 );

 ALTER TABLE CASUALTIME ADD FOREIGN KEY(Emp_ID) REFERENCES EMPLOYEE(Emp_ID);

 ALTER TABLE CASUALTIME ADD FOREIGN KEY(CasualJob_ID) REFERENCES JOBCASUALTIME(CasualJob_ID);

现在我想要名单列表,按工资排序的所有员工的完整地址,并指出员工是全职还是休闲。此处名称是名称列中表示的FName和LName以及街道,郊区州邮政编码(例如123 Anzac Pde,Maroubra NSW 2038)的组合,标记为ADDRESS。现在我知道在Join Statements的帮助下完成它。但是如果我们应该在不使用JOIN语句的情况下这样做那么SQL查询可以解决这个问题吗?

我需要根据员工的工作类型从FULLTIME和CASUAL表中获取ADDRESS TABLE和Salary的地址

2 个答案:

答案 0 :(得分:3)

您有表继承 - CASUALTIMEFULLTIME继承EMPLOYEE。假设一个员工必须是随意的或全职的,并且不能同时休闲和全职,那么你可以做的是使用一个工会来组合派生表中的临时和全职员工(我称之为{{1在连接到其余表之前获取单个“salary”字段(您将需要连接):

x

在单一栏目中列出年薪和小时费率似乎有些奇怪,因为它们具有不同的单位 - 将小时费率转换为年薪更有意义,反之亦然,因此它们具有相同的意义单元。

另外,您shouldn't be using SELECT e.Emp_FName, e.Emp_LName, a.Address_St, a.Address_City, a.Address_State, a.Address_PostCode, x.Salary FROM ( SELECT ct.emp_id, ct.Emp_salary_hourly AS Salary FROM CASUALTIME ct UNION SELECT ft.emp_id, ft.Emp_salary_yearly AS Salary FROM FULLTIME ft ) x INNER JOIN EMPLOYEE e on x.Emp_ID = e.Emp_ID INNER JOIN ADDRESS a on e.Address_ID_Resident = a.Address_ID -- Can join to JobType and AddressType same way 存储财务数据 - 而不是使用DOUBLE

我还假设DECIMAL是拼写错误 - 表格肯定是JOBTIME

答案 1 :(得分:2)

Full TimeCasual中保留两张几乎完全相同的表似乎是错误的做法。
我会将它们合并到一个名为Salary的表中,并将Emp_salary_yearlyEmp_salary_hourly重命名为Emp_salary,因为您已经在JobType_ID中都有CasualJob_ID列表。此外,FullTimeJob_IDFromDate列是多余且无用的。

请记住,任何员工的工资和工作类型都可能会发生变化,因此最好在工资表中保留ToDateNULL列(使用{{1在ToDate列中指示记录在当前日期仍然有效。

所以我的建议是这样的:

Create table Salary
(
    Emp_ID INT NOT NULL REFERENCES EMPLOYEE(Emp_ID),
    Emp_salary DOUBLE(10,2) NOT NULL,
    JobType_ID INT REFERENCES JOBTYPE(JobType_ID),
    FromDate date NOT NULL,
    ToDate date NULL,
    PRIMARY KEY(Emp_ID, FromDate)
);

注意:此表的主键是员工ID和起始日期。

这将产生一个简单的sql语句,如下所示:

SELECT CONCAT(Emp_FName, ' ', Emp_LName) As FullName, 
       CONCAT(Address_St, ' ', Address_City, ' ', Address_PostCode) As Address,
       Emp_salary_yearly,

       JobType_Desc,
       FromDate,
       ToDate
FROM EMPLOYEE e 
INNER JOIN ADDRESS a ON e.Address_ID_Resident = a.Address_ID
INNER JOIN Salary s ON(e.Emp_Id = Salary.Emp_Id)
INNER JOIN JOBTYPE j ON(s.JobType_ID = j.JobType_ID)

<强>更新 回答你的意见: 首先,不要使用隐式连接。 ANSI-SQL现在支持显式连接超过20年,并且在隐式连接中确实没有更好的结果 显式连接比隐式连接更易读,更容易处理。

其次,如果2个工资表不能组合成一个,你可以在两者上使用LEFT JOIN,或者在派生表上使用INNER JOIN,这是UNION之间的结果StuartLChis answer.

中的建议

这就是使用左连接的样子:

SELECT CONCAT(Emp_FName, ' ', Emp_LName) As FullName, 
       CONCAT(Address_St, ' ', Address_City, ' ', Address_PostCode) As Address,
       CASE WHEN Emp_salary_hourly IS NOT NULL THEN  
               CONCAT('$', LPAD(Emp_salary_hourly, 7, ' ') 
            WHEN Emp_salary_yearly IS NOT NULL THEN  
               CONCAT('$', LPAD(Emp_salary_yearly , 7, ' ')
       END As Emp_Salary, 
       JobType_Desc,
       FromDate,
       ToDate
FROM EMPLOYEE e 
INNER JOIN ADDRESS a ON e.Address_ID_Resident = a.Address_ID
INNER JOIN JOBTIME j ON(e.JobTime_ID = j.JobTime_ID )
LEFT JOIN FULLTIME f ON(e.Emp_Id = f.Emp_Id)
LEFT JOIN CASUALTIME c ON(e.Emp_Id = c.Emp_Id)

注意#1:这假设员工只能有一个工作时间 注意#2:如果FULLTIME和CASUALTIME都没有emp_id的记录,那么Emp_Salary将为null。