左连接重复

Duplicates on Left Join

这是一个 SQL 服务器问题。

我正在链接同一个数据库中的三个 table 并不断获取重复值。 Tables REF_Plan_Dictionary 和 REF_Plan_Assign_Default 将自行生成重复项,因为某些列将引用其他列中的多个子选项。 Table dev_OUT_MasterEmp 每个 EmpID 只会产生一条记录。

查询的目的是利用M.EmpID并将其他两个table的信息与这条信息进行匹配。重复项是 EmpID 重复多次但所有信息仅匹配一次的地方。这意味着我提到的子选项没有出现,因为其他两个 table 匹配正确。所以这不是匹配,而是相同信息重复的事实。

如何删除重复项?

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

这是我的结果示例:

这是tableREF_Plan词典:

这是tableREF_Plan_Assign_Default:

这是基本计划:

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

请修改输出列以满足您的需要。

避免不需要的重复记录的最佳方法是从一开始就计划好您认为重复的内容。换句话说,你想要每个员工 ID 一条记录还是你想要每个(员工,用户帐户)一条记录......等等。一旦你确定了你想要的输出的唯一键,那么你就可以构建你的查询它通过确保在连接该键时连接的双方只有 1 对 1 匹配。

例如,假设您只希望每个员工 ID 有一条记录。您可以从您的员工 table 开始,因为这是 table 的关键。然后,你加入其中的每个 table,你必须确保其中每个员工 ID 也只有一个记录。您可以使用包含分组依据的子查询来确保这一点。所以像:

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

在您的情况下,您似乎有两种类型的 "detail" table,并且您的员工记录有它们的外键。因此,如果您希望每位员工一条记录,请确保您只获得一条记录 returned 用于您的两个详细记录外键值。

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).

另一种消除除一个 "detail" 记录以外的所有记录的方法是过滤。所以也许您只想查看最近的记录。在那种情况下,您将使用过滤器来消除除您感兴趣的那个之外的所有重复项。您的子查询可能看起来像这样:

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

此子查询 return 每个 ID 仅有一条记录,并且它将是具有该 ID 最大 updated_date 的记录。

我不能告诉你应该如何构造你的子查询,因为我不能确切地说出你想要做什么,但一般的想法是从 table 或几个 tables 与您可以保证具有唯一密钥的连接。然后,您可以在之后对其他 table 或也具有相同唯一键的子查询进行连接和左连接。掌握了这个你就再也不会有意想不到的重复了。