2015-05-31 37 views
3

我有以下各表一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) 
); 

地址類型表就是告訴地址是否是住宅,辦公,郵政

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

JobTime表描述了員工的工作是全職還是休閒。

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語句的情況下執行此操作,那麼對於此問題可以使用SQL Query?

我需要從地址表和工資地址從FULLTIME休閒表根據作業類型的員工

+0

到目前爲止您嘗試了什麼查詢? – Sachu

+0

@Sachu我正面臨着如何將Emp_salary_yearly和Emp_salary_hourly結合到一個列中的問題? – ms8

+0

難道你不認爲地址表應該有列員工ID!我剛剛檢查了兩張桌子,但我不知道如何獲得員工地址! –

回答

3

您有表繼承 - CASUALTIMEFULLTIME繼承關EMPLOYEE。假設僱員必須是臨時的或全職的,並且不能同時休閒和全職,你可以做的就是使用一個工會將休閒和全職員工組合在派生表中(我稱之爲x),並獲得加入到表的其餘部分之前單一的「工資」字段(您需要連接):

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 

它似乎有點奇怪列出的年薪,並在單個列作爲一個每小時收費這些單位有不同的單位 - 將小時費率轉換爲年薪或反之亦然,因此他們擁有相同的單位。

此外,您shouldn't be usingDOUBLE存儲財務數據 - 而使用DECIMAL

我也認爲JOBTIME是一個錯字 - 表肯定是JobType

+0

我不想JOIN直接我想要使用WHERE子句連接多個表 – ms8

+0

使用[WHERE連接表被皺眉了](http://stackoverflow.com/a/1018825/314291) - 使用ANSI連接是前進的方向 - 我看不到無論如何,語法是'FROM(SELECT ...)x,Employee e,... WHERE e.Emp_ID = x.Emp_ID AND ...' – StuartLC

+0

您可以添加嗎?它到你的答案後,也需要打印結果按工資排序 – ms8

2

保持2個表是幾乎相同的Full TimeCasual我看來,像做錯事要做。
我將它們合併到名爲Salary一個表,並重新命名Emp_salary_yearlyEmp_salary_hourlyEmp_salary,因爲你已經擁有了列兩個表中JobType_ID。此外,CasualJob_IDFullTimeJob_ID列是多餘的和無用的。

請記住,對任何員工薪水和工作類型可能會改變,所以這將是一個好主意,讓FromDateToDate列在工資表,以及(在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) 
); 

注:此表的主鍵是兩個僱員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年的顯式連接,並且在隱式連接中確實沒有比這更好的了。
顯式連接更具可讀性,更容易處理隱式連接。其次,在兩個工資表不能合併爲一個的情況下,可以對兩者都使用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將爲空。

+0

我不想直接加入我想使用WHERE子句連接多個表。我也不能像這樣合併兩個表。原因是我只在這裏提供了一部分表。我在項目 – ms8

+0

中以不同方式使用這兩個表格。另外,您可能沒有注意到它們都依賴於兩個不同的表名稱JOBFULLTIME和JOBCASUALTIME – ms8

+0

請參閱我編輯的答案。 –

相關問題