查找比较PostgreSQL中2个字段的重复项

时间:2015-04-16 10:09:18

标签: sql postgresql duplicates

我有一张包含以下数据的表

id  parent_id   ascii_name  lang
1   123         Foo         en
2   123         Foo         fi
3   456         Bar         it
4   345         Foo         fr

我想选择具有相同parent_idascii_name的所有记录,基本上我想要这个:

id  parent_id   ascii_name  lang
1   123         Foo         en
2   123         Foo         fi

现在我能够选择只有ascii_name

的记录
id  parent_id   ascii_name  lang
1   123         Foo         en
2   123         Foo         fi
4   345         Foo         fr

使用查询:

SELECT * FROM table WHERE ascii_name in 
(SELECT ascii_name FROM table GROUP By ascii_name
 HAVING "count"(ascii_name) > 1)

我不知道如何将parent_id放入等式中。

更新

我使用@jakub和@mucio答案找到了正确的查询:

SELECT * FROM geo_nodes_copy WHERE (parent_id,ascii_name) in 
(SELECT parent_id, ascii_name 
 FROM geo_nodes_copy 
 GROUP By parent_id, ascii_name 
 HAVING count (1) > 1)

现在,唯一的问题可能是查询速度。

4 个答案:

答案 0 :(得分:1)

使用以下查询作为子查询

   SELECT parent_id, 
          ascii_name 
     FROM table 
 GROUP By parent_id, 
          ascii_name 
   HAVING count (1) > 1

这将使所有情侣parent_id / ascii_name返回多行。

答案 1 :(得分:1)

好吧,因为它是pg你可以使用行结构:

SELECT * FROM table WHERE (ascii_name,parent_id) in 
(SELECT ascii_name, parent_id FROM table GROUP By ascii_name, parent_id HAVING Count(ascii_name) > 1)

答案 2 :(得分:1)

使用窗口功能:

select t.*
from (select t.*, count(*) over (partition by ascii_name, parent_id) as cnt
      from table t
     ) t
where cnt >= 2;

在某些情况下,使用exists可能会快一点:

select t.*
from table t
where exists (select 1
              from table t2
              where t2.ascii_name = t.ascii_name and
                    t2.parent_id = t.parent_id and
                    t2.id <> t.id
             );

为了提高效果,请在table(ascii_name, parent_id, id)上添加一个索引。

答案 3 :(得分:0)

假设parentid将始终共享相同的asciiname

SELECT a.* 
FROM table a
WHERE a.ascii_name =
(SELECT b.ascii_name 
 FROM table b
 WHERE a.parent_id = b.parent_id)