1

I've a table with the following data

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

I want to select all the records that have the same parent_id and ascii_name, basically I want this:

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

Right now I was able to select the records having only the same ascii_name:

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

using the query:

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

I don't know how to put the parent_id into the equation.

Update

I found the right query using both @jakub and @mucio answers:

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)

Now, the only problem is, maybe, the query speed.

Community
  • 1
  • 1
Fed03
  • 575
  • 5
  • 16

4 Answers4

1

Use the following query as subquery

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

This will return you all the couple parent_id/ascii_name with multiple rows.

mucio
  • 7,014
  • 1
  • 21
  • 33
1

Well, since it's pg you can use a row construct:

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)
Jakub Kania
  • 15,665
  • 2
  • 37
  • 47
  • 1
    this will not run because you need to add `parent_id` in the _GROUP BY_ clause – Vivek S. Apr 16 '15 at 11:31
  • @vivek yeah, that's what I used, the problem now is performance – Fed03 Apr 16 '15 at 13:06
  • 1
    @Fed03 [This answer](http://stackoverflow.com/questions/29671548/find-duplicates-comparing-2-fields-in-postgresql/29672388#29672388) can be use for better performance – Vivek S. Apr 17 '15 at 04:34
1

Use window functions:

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

Under some circumstances, it might be a bit faster to use 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
             );

For performance, include an index on table(ascii_name, parent_id, id).

Gordon Linoff
  • 1,242,037
  • 58
  • 646
  • 786
0

Assuming that a parentid will always share the same asciiname

SELECT a.* 
FROM table a
WHERE a.ascii_name =
(SELECT b.ascii_name 
 FROM table b
 WHERE a.parent_id = b.parent_id)
Matt
  • 14,906
  • 27
  • 99
  • 149