【问题标题】:Get top first record from duplicate records having no unique identity从没有唯一标识的重复记录中获取第一条记录
【发布时间】:2011-01-11 19:05:03
【问题描述】:

我需要从下表中的每组重复记录中提取第一行。 我需要在视图中使用这个查询

请不要使用临时表,因为我已经通过添加标识列和 min 函数和 group by 来完成它。我需要没有临时表或表变量的解决方案

这只是示例数据。原始表中有 1000 条记录,我只需要前 1000 条的结果,所以我不能使用 distinct

我使用的是 SQL Server 2005

【问题讨论】:

    标签: sql sql-server-2005 tsql


    【解决方案1】:

    查找已订购 1 次或多次的所有产品...(重复记录的种类)

    SELECT DISTINCT * from [order_items] where productid in 
    (SELECT productid 
      FROM [order_items]
      group by productid 
      having COUNT(*)>0)
    order by productid 
    

    要选择最后插入的那些...

    SELECT DISTINCT productid, MAX(id) OVER (PARTITION BY productid) AS LastRowId from [order_items] where productid in 
    (SELECT productid 
      FROM [order_items]
      group by productid 
      having COUNT(*)>0)
    order by productid 
    

    【讨论】:

      【解决方案2】:

      答案具体取决于您所说的“前 1000 条不同”记录是什么意思。

      如果您的意思是要返回最多 1000 条不同的记录,而不管表中有多少重复项,请这样写:

      SELECT DISTINCT TOP 1000 id, uname, tel
      FROM Users
      ORDER BY <sort_columns>
      

      如果您只想搜索表中的前 1000 行,并且可能返回少于 1000 个不同的行,那么您可以使用子查询或 CTE 编写它,如下所示:

      SELECT DISTINCT *
      FROM
      (
          SELECT TOP 1000 id, uname, tel
          FROM Users
          ORDER BY <sort_columns>
      ) u
      

      如果您不关心返回哪些记录,ORDER BY 当然是可选的。

      【讨论】:

        【解决方案3】:

        有时您可以像这样使用 CROSS APPLY 运算符:

        select distinct result.* from data d
        cross apply (select top 1 * from data where data.Id = d.Id) result
        

        在这个查询中,我只需要选择在我的数据中自然发生的许多重复项中的第一个。它适用于 SQL Server 2005+ 数据库。

        【讨论】:

        • 谢谢。这解决了我们在重复数据方面经常遇到的一个非常大的问题。
        • 我只是在找这个..非常感谢!!
        • 我不明白最后的select distinct result.*result,这是怎么回事
        • @xinthose 我在交叉应用运算符中创建了一个虚拟表,并将其命名为result。此虚拟表通过 Id 列与“核心”表数据连接。另请注意,我还为data 表提供了一个新别名,名为d,因此我可以在交叉应用中定义的“虚拟表”中​​引用它。最后,我只想返回这个新的虚拟表,名为result。我需要要求 distinct 因为数据集通常有很多重复。
        【解决方案4】:

        您可以尝试以下方法:

        1. 创建一个视图,该视图仅选择原始表中的所有列,但添加一个额外的数字列,该列的值随每条记录\行而增加。您可能需要将此列设置为非整数列(例如,为每条记录增加 1.00 以在 RANK() SQL 语句中使用它)。

        2. 还添加另一列(例如“RecordRank”)以包含所有列的计算排名值,使用 RANK() OVER SQL 子句为该列创建值 - 请参阅下面的参考资料。 RANK 语句允许您对记录进行分区,然后根据 order by 列中的值对每个分区记录进行排序(使用从步骤 1 开始增加值的 Column 作为您的 order by)。您在分区子句中使用具有相同数据的列,因此所有这些相似的重复项都被分区或分组在一起,然后按额外列中的值排序(从第 1 步开始按列排序)。

          http://msdn.microsoft.com/en-us/library/ms189461.aspx

        3、上面的视图创建成功后,再写一个视图只选择'RecordRank' = 1的记录

        这应该只从重复项或分区中选择每条记录之一。

        希望这会有所帮助 - malcom sankoh

        【讨论】:

          【解决方案5】:

          SELECT DISTINCT 没有帮助吗?我想它会返回你想要的结果。

          【讨论】:

          • 对不起,我的问题中没有提到这只是示例数据。原始表中有 1000 条记录,我只需要前 1000 条的结果,所以不能使用 distinct
          【解决方案6】:

          使用 DISTINCT 应​​该可以做到:

          SELECT DISTINCT id, uname, tel
          FROM YourTable
          

          虽然您确实可以在该表上使用主键,但这是一种唯一标识每条记录的方法。我会考虑在桌子上贴一个 IDENTITY 列

          【讨论】:

          • 对不起,我的问题中没有提到这只是示例数据。原始表中有 1000 条记录,我只需要前 1000 条的结果,所以不能使用 distinct
          【解决方案7】:

          您最好的办法是修复数据库设计并将身份列添加到表中。为什么你的桌子一开始就没有桌子?尤其是有重复记录的!显然,数据库本身需要重新设计。

          为什么你必须在视图中显示这个,为什么你的临时表解决方案不是一个有效的解决方案?对于一个完美的数据库来说,视图通常不是一件好事。

          【讨论】:

          • 您是对的,但请告诉我 1) 我如何说服需要 View 中此解决方案的经理。 2)我从客户那里得到了数据库设计,我必须坚持这个设计。
          【解决方案8】:

          这里有两种解决方案,我使用的是Oracle SQL server:

          1) 使用 over 子句:

              with org_table as
           (select 1 id, 'Ali' uname
              from dual
            union
            select 1, 'June'
              from dual
            union
            select 2, 'Jame'
              from dual
            union
            select 2, 'July' from dual)
          select id, uname
            from (select a.id,
                         a.uname,
                         ROW_NUMBER() OVER(PARTITION BY a.id ORDER BY a.id) AS freq
          
                    from org_table a)
           where freq = 1
          

          2) 使用子查询:

              with org_table as
           (select 1 id, 'Ali' uname
              from dual
            union
            select 1, 'June'
              from dual
            union
            select 2, 'Jame'
              from dual
            union
            select 2, 'July' from dual)
          
          select a.id,
                 (select b.uname
                    from org_table b
                   where b.id = a.id
                     and rownum = 1)
            from (select distinct id from org_table) a
          

          【讨论】:

            【解决方案9】:
            SELECT TOP 1000 MAX(tel) FROM TableName WHERE Id IN 
            (
            SELECT Id FROM TableName
            GROUP BY Id
            HAVING COUNT(*) > 1
            ) 
            GROUP BY Id
            

            【讨论】:

            • 这个答案可能会受益于一些关于它如何解决问题的解释,以及它与已经提供的其他答案的不同之处。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-05-08
            • 2022-11-30
            • 1970-01-01
            • 2019-12-28
            相关资源
            最近更新 更多