删除左连接查询中的重复行

时间:2018-02-28 14:06:55

标签: sql sql-server tsql sql-server-2014

      SELECT Rec.[Reg_ID]
      ,Rec.[Reg_No]
      ,Rec.[Case_ID]
      ,Det.Deleted AS CaseDeleted
      ,[Status].[Status]
      ,Det.[Unit_Submission_Date] AS [Signature]
      ,TD.TargetDate AS [Target]
      ,TD.TargetID
      FROM [dbo].[Regestrations] Rec
      LEFT JOIN [dbo].[Reg_Details] Det ON Rec.Case_ID   = Det.CaseID
      LEFT JOIN [dbo].[lkpStatus] [Status] ON Rec.Status_ID = [Status].StatusID
      LEFT JOIN TargetDate TD ON TD.RecommId = Rec.Reg_ID
      WHERE (Det.MissionID = 50 AND [Status].[Status] = 1 AND Rec.Deleted = 0 AND Det.Deleted = 0)
      GROUP BY Rec.[Reg_ID],Rec.[Reg_No],Rec.[Case_ID]
      ,[Status].[Status]
      ,Det.[Unit_Submission_Date]
      ,TD.TargetDate
      ,Det.Deleted
      ,TD.TargetID
      ORDER BY TD.TargetID desc

我有上面的查询应该返回唯一Rec.[Reg_No]的行。但是联接表格TargetDate可能会有重复的Rec.[Reg_ID],如果是这样,我的结果中会出现重复的Rec.[Reg_No]行。

TargetDate有一个日期时间列,因此我想通过从表Rec.[Reg_No]中选择包含最新日期值的1行来消除重复的TargetDate

如何修改我的Join条件或查询where子句以实现上述目的?

3 个答案:

答案 0 :(得分:2)

一种方法是使用诸如ROW_NUMBER()之类的窗口函数,它将根据指定的分区生成序列号。然后可以使用此生成的数字来获取最新的行。

SELECT  Reg_ID, Reg_No, Case_ID, CaseDeleted, [Status], Signature, [Target], TargetID
FROM
(
    SELECT Rec.[Reg_ID]
            ,Rec.[Reg_No]
            ,Rec.[Case_ID]
            ,Det.Deleted AS CaseDeleted
            ,[Status].[Status]
            ,Det.[Unit_Submission_Date] AS [Signature]
            ,TD.TargetDate AS [Target]
            ,TD.TargetID
            ,RN = ROW_NUMBER() OVER (PARTITION BY Rec.[Reg_No] ORDER BY TD.TargetID DESC)
    FROM [BOI].[dbo].[Regestrations] Rec
        LEFT JOIN [dbo].[Reg_Details] Det ON Rec.Case_ID   = Det.CaseID
        LEFT JOIN [dbo].[lkpStatus] [Status] ON Rec.Status_ID = [Status].StatusID
        LEFT JOIN TargetDate TD ON TD.RecommId = Rec.Reg_ID
    WHERE (Det.MissionID = 50 AND [Status].[Status] = 1 AND Rec.Deleted = 0 AND Det.Deleted = 0)

) subQuery
WHERE RN = 1
ORDER BY TargetID desc

答案 1 :(得分:1)

如果您从TD.TargetDate子句中删除GROUP BY并计算输出中真正需要的内容,此查询可以正常运行 - MAX(TD.TargetDate)

但最好是避免GROUP BY条款:

  ...
  FROM [BOI].[dbo].[Regestrations] Rec
  LEFT JOIN [dbo].[Reg_Details] Det ON Rec.Case_ID   = Det.CaseID
  LEFT JOIN [dbo].[lkpStatus] [Status] ON Rec.Status_ID = [Status].StatusID
  OUTER APPLY(
    SELECT TOP 1 td.TargetDate, td.TargetID
    FROM TargetDate TD
    WHERE TD.RecommId = Rec.Reg_ID
    ORDER BY TD.TargetDate DESC
  ) td
  ...

答案 2 :(得分:0)

您应首先为每个RecommIdRecommId找到最新的TargetDate。然后,您可以使用与TargetDate表的常规联接,同时匹配TargetDateSELECT Rec.[Reg_ID] ,Rec.[Reg_No] ,Rec.[Case_ID] ,Det.Deleted AS CaseDeleted ,[Status].[Status] ,Det.[Unit_Submission_Date] AS [Signature] ,TD.TargetDate AS [Target] ,TD.TargetID FROM [BOI].[dbo].[Regestrations] Rec LEFT JOIN [dbo].[Reg_Details] Det ON Rec.Case_ID = Det.CaseID LEFT JOIN [dbo].[lkpStatus] [Status] ON Rec.Status_ID = [Status].StatusID LEFT JOIN (SELECT RecommId, MAX(TargetDate) MaxTargetDate GROUP BY RecommId) TDWithLatestDate ON TDWithLatestDate.RecommId = Rec.Reg_ID LEFT OUTER JOIN TargetDate ON TD.RecommId = TDWithLatestDate.RecommId AND TD.TargetDate = TDWithLatestDate.MaxTargetDate WHERE (Det.MissionID = 50 AND [Status].[Status] = 1 AND Rec.Deleted = 0 AND Det.Deleted = 0 ) GROUP BY Rec.[Reg_ID] ,Rec.[Reg_No] ,Rec.[Case_ID] ,[Status].[Status] ,Det.[Unit_Submission_Date] ,TD.TargetDate ,Det.Deleted ,TD.TargetID ORDER BY TD.TargetID desc

尝试此查询:

int tcflow(int fildes, int action);

如果您希望在多个记录争用最新时避免平局,则可以改进此查询。