【问题标题】:Find rows with duplicate values in a column查找列中具有重复值的行
【发布时间】:2014-05-08 12:10:45
【问题描述】:

我有一张桌子author_data

 author_id | author_name
 ----------+----------------
 9         | ernest jordan
 14        | k moribe
 15        | ernest jordan
 25        | william h nailon 
 79        | howard jason
 36        | k moribe

现在我需要结果为:

 author_id | author_name                                                  
 ----------+----------------
 9         | ernest jordan
 15        | ernest jordan     
 14        | k moribe 
 36        | k moribe

也就是说,对于出现重复的名称,我需要 author_id。我试过这个说法:

select author_id,count(author_name)
from author_data
group by author_name
having count(author_name)>1

但它不起作用。我怎样才能得到这个?

【问题讨论】:

    标签: sql postgresql duplicates aggregate-functions window-functions


    【解决方案1】:

    你已经成功了一半。您只需使用已识别的Author_IDs 并获取其余数据。

    试试这个..

    SELECT author_id, author_name
    FROM author_data
    WHERE author_id in (select author_id
            from author_data
            group by author_name
            having count(author_name)>1)
    

    【讨论】:

      【解决方案2】:

      我建议在子查询中使用window function

      SELECT author_id, author_name  -- omit the name here if you just need ids
      FROM (
         SELECT author_id, author_name
              , count(*) OVER (PARTITION BY author_name) AS ct
         FROM   author_data
         ) sub
      WHERE  ct > 1;
      

      您将认识基本的聚合函数count()。它可以通过附加一个OVER 子句变成一个窗口函数——就像任何其他聚合函数一样。

      这样它会计算每个分区的行数。瞧。

      必须在子查询中完成,因为不能在同一 SELECTWHERE 子句中引用结果(发生在 WHERE 之后)。见:

      在没有窗口函数的旧版本(v.8.3 或更早版本)中 - 或者一般来说 - 这种替代方法执行得非常快:

      SELECT author_id, author_name  -- omit name, if you just need ids
      FROM   author_data a
      WHERE  EXISTS (
         SELECT FROM author_data a2
         WHERE  a2.author_name = a.author_name
         AND    a2.author_id <> a.author_id
         );
      

      如果您关心性能,请在author_name 上添加索引。

      【讨论】:

        【解决方案3】:

        您可以将表连接到自身上,这可以通过以下任一查询来实现:

        SELECT a1.author_id, a1.author_name
        FROM authors a1
        CROSS JOIN authors a2
          ON a1.author_id <> a2.author_id
          AND a1.author_name = a2.author_name;
        
        -- 9 |ernest jordan
        -- 15|ernest jordan
        -- 14|k moribe
        -- 36|k moribe
        
        --OR
        
        SELECT a1.author_id, a1.author_name
        FROM authors a1
        INNER JOIN authors a2
          WHERE a1.author_id <> a2.author_id
          AND a1.author_name = a2.author_name;
        
        -- 9 |ernest jordan
        -- 15|ernest jordan
        -- 14|k moribe
        -- 36|k moribe
        

        【讨论】:

          猜你喜欢
          • 2012-09-26
          • 2011-06-23
          • 1970-01-01
          • 1970-01-01
          • 2020-03-04
          • 1970-01-01
          • 2015-12-18
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多