2015-05-20 91 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是详细表中的属性字段。 –