Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 员工详细信息及其工作类型_Mysql_Sql - Fatal编程技术网

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

Mysql 员工详细信息及其工作类型,mysql,sql,Mysql,Sql,我有一个带有以下表格的DB: 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(

我有一个带有以下表格的DB:

 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)
);
工作时间表描述了员工的工作是全职还是临时工作

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)。现在我知道了如何借助Join语句来实现它。但如果我们不使用JOIN语句,那么SQL查询能解决什么问题呢


我需要从地址表中获取地址,从全职和临时表中获取工资,具体取决于员工的工作类型

保留两个几乎相同的表,用于
全职
临时
,在我看来,这样做似乎是错误的。
我会将它们合并到一个名为
Salary
的表中,并将
Emp\u Salary\u yearly
Emp\u Salary\u hourly
重命名为
Emp\u Salary
,因为这两个表中都有
JobType\u ID
列。另外,
CasualJob\u ID
FullTimeJob\u ID
列是多余的,没有用处

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

所以我的建议是这样的:

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)
);
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)
注意:此表的主键是员工id和起始日期

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

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)
);
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多年了,隐式连接真的再好不过了。
显式联接比隐式联接可读性更强,更易于处理

其次,如果无法将两个薪资表合并为一个,则可以对这两个表使用左联接,也可以对派生表使用内部联接,该派生表是两个表合并的结果,如中所建议的

这是使用左连接时的情况:

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:如果全职员工和临时员工都没有emp\u id的记录,则emp\u工资将为空

您有表继承-
CASUALTIME
FULLTIME
继承
EMPLOYEE
。假设一名员工必须是临时员工或全职员工,并且不能同时是临时员工和全职员工,那么您可以使用工会将临时员工和全职员工合并到一个派生表中(我称之为
x
),并在加入其他表之前获得一个“salary”字段(您需要加入):

在一列中列出年薪和小时费率似乎有点奇怪,因为它们有不同的单位——将小时费率转换为年薪或将小时费率转换为年薪更有意义,反之亦然,因此它们有相同的单位

另外,您可以使用
DOUBLE
来存储财务数据,而不是使用
DECIMAL


我还假设
JOBTIME
是一个输入错误-该表肯定是
JobType

您到目前为止尝试了什么查询?@Sachu我面临的问题是如何将Emp\u salary\u year和Emp\u salary\u hourly合并到一个列中?您不认为地址表应该有一个引用员工id的列吗!!我刚查了前两张表,但我不知道你还能怎么得到员工地址@ubaidgadha employee表与address表之间有一个FK。有些员工可能住在一起,所以这是正确的关系。双倍(10,2)??我能找份工作吗。我不介意我不知道我到底能挣多少钱,所以我可能没有十进制数据类型我不想直接连接我想使用WHERE子句连接多个表使用ANSI连接是前进的方向我不明白你为什么想养成坏习惯?在任何情况下,语法都是FROM(SELECT…)x,Employee e。。。如果e.Emp_ID=x.Emp_ID和…你能把它添加到你的回复帖子中吗?我还需要打印按薪水排序的结果吗?否,MySql支持ANSI联接,你应该使用这些联接,而不是
WHERE
子句请注意,这不是一个代码编写服务-你正在添加新的需求。我不想直接连接我想使用WHERE子句连接多个表。我也不能像这样合并这两个表。原因是我只在这里提供了部分表。在我的项目中,我以不同的方式将这两个表作为一个整体使用。您可能没有注意到,它们都依赖于两个不同的表名称JOBFULLTIME和JobCasualTime。如果所有货币值都应使用美元符号($)打印,小数点后两位数字,小数点前有7位数的空格参见如何在MySqlIt中格式化数据不要找7个空格