2015-05-20 90 views
0

這是一個SQL Server問題。左連接複製

我連接來自同一個數據庫的三個表,並不斷獲取重複值。表REF_Plan_Dictionary和REF_Plan_Assign_Default將自行生成重複項,因爲某些列將引用其他列中的多個子選項。表dev_OUT_MasterEmp只會爲每個EmpID生成一條記錄。

該查詢的目的是使用M.EmpID並將來自其他兩個表的信息與這條信息相匹配。重複項是EmpID重複多次的位置,但所有信息只匹配一次。這意味着我提到的子選項沒有顯示出來,因爲其他兩個表匹配正確。所以這不是匹配,這是相同的信息重複的事實。

我該如何擺脫重複?

SELECT M.EmpId 
     ,EmpName 
     ,[UserId] 
     ,PA.Plan_Dict_Id 
     ,m.Job_Code 
     ,Dept_Num 
     ,PayGroup 
     ,D.Plan_Name 
     ,Plan_Desc 
     ,M.[File_Nbr] 
     ,[Mgr_EmpId] 
     ,[Work_Location] 
     ,[Emp_Tenure] 
     ,[Emp_Status] 
     ,[Plan_Eligibility] 
     ,M.[Function_Role_Code] 
     ,[Hire_Date] 
     ,[Job_Entry_Date] 
     ,[Term_Date] 
     ,[Dept_Num] 
     ,[TeamID] 
     ,[CCGroup] 
     ,[Channel] 
     ,[Organization] 
     ,[Hourly_Rate] 
     ,[HC] 
    FROM [Compensation].[dbo].[dev_OUT_MasterEmp] M 
    left join Compensation..REF_Plan_Dictionary D on M.Plan_Id = D.Plan_Dict_Id 
    left join Compensation..REF_Plan_Assign_Default PA on M.Plan_Id = PA.Plan_Dict_Id 

這是我的結果的一個例子: enter image description here

這是表REF_Plan詞典: enter image description here

這是表REF_Plan_Assign_Default: enter image description here

+0

樣本數據/輸出將有所幫助。 – canon

+0

如果您的映射表中有多個條目,則結果中將有重複的EmpId。要刪除重複的結果,您需要先在EmpId上創建結果,然後再次將結果與Employee表結合以添加其他信息。 – Tim3880

+0

@ Tim3880我曾想過這件事。問題是沒有其他表有員工ID,所以我不得不引用其他列加入他們。 – MHeath

回答

1

這是基本的計劃:

SELECT EMP.*, PL.Plan_NAME , PL.Plan_DESC, 
MAP.Job_Code, MAP.PayGroup 
FROM [Compensation].[dbo].[dev_OUT_MasterEmp] EMP 
JOIN (
    SELECT M.EMPID, MAX(PA.Plan_Dict_Id) AS M_PLAN_ID, 
    MAX(PA.JobCode) AS Job_Code, MAX(PA.PayGroup) AS PayGroup 
    FROM [Compensation].[dbo].[dev_OUT_MasterEmp] M 
    LEFT JOIN Compensation..REF_Plan_Assign_Default PA 
    ON M.PLAN_ID = PA.Plan_Dict_Id 
    GROUP BY M.EMPID 
) MAP 
ON MAP.EMPID= EMPS.EMPID 
JOIN Compensation..REF_Plan_Dictionary PL 
ON MAP.M_PLAN_ID = PL.PLAN_DICT_ID 

請修改輸出欄以滿足您的需求。

+0

完成!它工作但花了很長時間來處理。當然不是你的錯。我會給我的選擇一看,並將它們配對一下,但這正是我需要的。 – MHeath

0

避免不必要的重複記錄的最佳方法是從一開始就規劃出您認爲重複的內容。換句話說,你想每個員工ID有一個記錄嗎?或者你想每個員工(用戶,用戶賬戶)有一個記錄...等等。一旦你確定了你想要的輸出的唯一鍵,它通過確保在加入該密鑰時加入雙方只有1比1的比賽。

因此,例如,假設您只需要每個員工ID一條記錄。您可以從員工表開始,因爲這是該表的關鍵。然後,每加入一張表格,您都必須確保每個員工ID中只有一條記錄。您可以通過包含group by的子查詢來確保這一點。所以像這樣:

Select ... 
from employees 
join 
    (Select employeeid, sum(field1), max(field2)... 
    from employeedetail 
    group by employeeid 
    ) employeedetails 

它看起來像你的情況,你有兩種類型的「細節」表,你的員工記錄有一個外鍵給他們。因此,如果您想爲每位員工創建一條記錄,那麼請確保您只獲取一條記錄爲您的兩個詳細記錄外鍵值返回一條記錄。

select m.* 
FROM [Compensation].[dbo].[dev_OUT_MasterEmp] M 
left join 
    (
    select Plan_Dict_Id, aggregate_function(field1) as field1... etc. 
    Compensation..REF_Plan_Dictionary 
    group by Plan_Dict_Id 
    ) D 
on M.Plan_Id = D.Plan_Dict_Id 
left join 
    (
    select Plan_Dict_Id, aggregate_function(field1) as field1... etc. 
    Compensation..REF_Plan_Assign_Default 
    group by Plan_Dict_Id 
    ) PA 
on M.Plan_Id = PA.Plan_Dict_Id 

在子查詢,你要上的字段(Field1以上),因爲有可能是重複使用聚合函數。例如,也許有一個支付字段,並且您想知道對此plan_id所做的總付款,那麼您將使用sum(Payment)

除去一個「詳細」記錄的另一種方法是過濾。所以也許你只想看最新的紀錄。在這種情況下,您可以使用過濾器來消除所有重複項目,但您感興趣的項目不會重複。你的子查詢可能是這個樣子:

select * 
from DetailTable 
join (
    select ID, MAX(updated_date) updated_date 
    from DetailTable 
    group by ID 
    ) MaxRecord 
on DetailTable.ID = MaxRecord.ID 
    and DetailTable.updated_date = MaxRecord.updated_date 

該子查詢將返回每ID只有一個記錄,這將是具有最大的updated_date該ID的記錄。

我不能告訴你如何構建你的子查詢,因爲我不能確切地告訴你正在做什麼,但總的想法是從一個表或兩個表開始加入,你可以保證有一個獨特的關鍵。然後,可以將連接和離開後的連接添加到也具有相同唯一鍵的其他表或子查詢。掌握這一點時,您再也不會有意想不到的重複。

+0

「(field1)」是員工嗎?其他表格沒有員工特定的數據。連接這三個表的唯一信息之一是其他表上重複的計劃ID。 – MHeath

+0

我詳細闡述了我的答案。示例子查詢中的Field1是詳細表中的屬性字段。 –