patternsqlMinor
Select all rows where a column value occurs more than once
Viewed 0 times
oncerowscolumnallwheremorethanvalueselectoccurs
Problem
I have a following table structure in Postgres:
How I can select all row where
I tried this one query, but it does not return what I expect:
id | account_id | plan_id | active
----+------------+---------+--------
1 | 0cYd7Ak | 1 | f
2 | Uk02q1d | 1 | t
3 | eRlk810 | 2 | f
4 | Uk02q1d | 2 | t
5 | 0cYd7Ak | 1 | t
6 | yT3nv3p | 3 | tHow I can select all row where
account_id occurs more than once? For the example above it will return rows 1, 2, 4, 5I tried this one query, but it does not return what I expect:
select * from table_name t1
where (select count(*) from table_name t2
where t1.account_id = t2.account_id) > 1
order by t1.account_id;Solution
Your query seems correct (although it may not be the most efficient).
There are many ways to write this type of query. For example, you could use
Another method is to use a subquery or CTE and window aggregate:
Or use a subquery to find the accounts that have more than one occurrences and then join to the table:
There are many ways to write this type of query. For example, you could use
EXISTS to avoid counting in the correlated subquery:select * from table_name t1
where exists
(select 1 from table_name t2
where t1.account_id = t2.account_id and t1.id <> t2.id)
;Another method is to use a subquery or CTE and window aggregate:
select id, account_id, plan_id, active
from
( select *,
count(1) over (partition by account_id) as occurs
from table_name
) AS t
where occurs > 1 ;Or use a subquery to find the accounts that have more than one occurrences and then join to the table:
select t.*
from
( select account_id
from table_name
group by account_id
-- having count(1) > 1
having min(id) <> max(id) -- variation with same result
) as c
join table_name as t
on t.account_id = c.account_id ;Code Snippets
select * from table_name t1
where exists
(select 1 from table_name t2
where t1.account_id = t2.account_id and t1.id <> t2.id)
;select id, account_id, plan_id, active
from
( select *,
count(1) over (partition by account_id) as occurs
from table_name
) AS t
where occurs > 1 ;select t.*
from
( select account_id
from table_name
group by account_id
-- having count(1) > 1
having min(id) <> max(id) -- variation with same result
) as c
join table_name as t
on t.account_id = c.account_id ;Context
StackExchange Database Administrators Q#212624, answer score: 8
Revisions (0)
No revisions yet.