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

问题描述 投票:0回答:3
      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子句来实现上述目的?

sql sql-server tsql sql-server-2014
3个回答
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
投票

一种方法是使用诸如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

0
投票

您应该首先找到每个Reg_IDRecommId的最新TargetDate。然后,您可以使用与TargetDate表的常规连接,同时匹配RecommIdTargetDate

试试这个查询:

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 [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

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

© www.soinside.com 2019 - 2024. All rights reserved.