【问题标题】:Need assistance removing duplicates in SQL需要帮助删除 SQL 中的重复项
【发布时间】:2021-01-02 15:58:38
【问题描述】:

我希望合并来自两个表的数据,但遇到了一些重复的问题。 Table1 包含基本的用户信息,例如名字和姓氏。表 2 包含地址、城市和邮编等附加信息。我遇到的问题是某些用户在 Table2 中有多个条目,因为他们的地址已更新。

我尝试了左连接。它几乎可以工作,但我似乎无法弄清楚如何删除重复的条目。我只需要最新的地址条目,它可以由较高的“AutoID”标识符确定(参见图片以获取我所引用的示例)。

想法?

Sample Tables for visualization

SELECT TOP (9000) [Table1].[ID]
      ,[Table1].[LastName]
      ,[Table1].[FirstName]
      ,[Table2].Address1
      ,[Table2].[City]
      ,[Table2].[State]
      ,[Table2].ZipCode
FROM *****.dbo.Table1
LEFT JOIN *****.dbo.Table2 ON (Table1.ID = Table2.ID)

【问题讨论】:

    标签: sql sql-server subquery left-join greatest-n-per-group


    【解决方案1】:

    使用DISTINCT 关键字:

    SELECT DISTINCT TOP (9000) [Table1].[ID]
          ,[Table1].[LastName]
          ,[Table1].[FirstName]
          ,[Table2].Address1
          ,[Table2].[City]
          ,[Table2].[State]
          ,[Table2].ZipCode
    FROM *****.dbo.Table1
    LEFT JOIN *****.dbo.Table2 ON (Table1.ID = Table2.ID)
    

    【讨论】:

      【解决方案2】:

      你可以使用窗口函数:

      SELECT TOP (9000) 
             t1.[ID]
            ,t1.[LastName]
            ,t1.[FirstName]
            ,t2.Address1
            ,t2.[City]
            ,t2.[State]
            ,t2.ZipCode
      FROM *****.dbo.Table1 t1
      LEFT JOIN (
          SELECT t2.*, ROW_NUMBER() OVER(PARTITION BY id ORDER BY AutoID DESC) rn
          FROM *****.dbo.Table2 t2
      ) t2 ON t1.ID = t2.ID AND r2.rn = 1
      

      子查询对具有相同ID 的记录按降序排列AutoID。然后,外部查询过滤每个组的顶部记录。

      另一种选择是横向连接:

      SELECT TOP (9000) 
             t1.[ID]
            ,t1.[LastName]
            ,t1.[FirstName]
            ,t2.Address1
            ,t2.[City]
            ,t2.[State]
            ,t2.ZipCode
      FROM *****.dbo.Table1 t1
      OUTER APPLY(
          SELECT TOP (1) t2.*
          FROM *****.dbo.Table2 t2
          WHERE t2.ID = t1.ID
          ORDER BY t2.AutoID DESC
      ) t2
      

      旁注:外部查询使用TOP,但数据集未排序。考虑在查询中添加适当的ORDER BY 子句,以使结果集可预测且稳定。

      【讨论】:

      • 如果我尝试横向连接,则会得到“无法绑定多部分标识符“t2.Address1””
      • @iTDeStruXion:这将是令人惊讶的 - 除非 Table2 没有名为 Address1 的列(在这种情况下,您的原始查询也会失败)。
      【解决方案3】:

      您可以使用解析函数来获得所需的输出 -

      SELECT TOP (9000) [Table1].[ID]
             ,[Table1].[LastName]
             ,[Table1].[FirstName]
            ,[Table2].Address1
            ,[Table2].[City]
            ,[Table2].[State]
            ,[Table2].ZipCode
      FROM *****.dbo.Table1
      LEFT JOIN (select t2.*, row_number() over(partition by id order by autoid desc) as seq_num from *****.dbo.Table2 t2 ) Tb2 ON (Table1.ID = Tb2.ID)
      Where Tb2.seq_num = 1;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-08-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-06
        • 2015-09-17
        相关资源
        最近更新 更多