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