选择列值出现多次的所有行

Ale*_*ein 1 postgresql

我在 Postgres 中有以下表结构:

 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 |      t  
Run Code Online (Sandbox Code Playgroud)

如何选择account_id出现多次的所有行?对于上面的示例,它将返回第 1、2、4、5 行

我试过这个查询,但它没有返回我所期望的:

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;
Run Code Online (Sandbox Code Playgroud)

ype*_*eᵀᴹ 6

您的查询似乎是正确的(尽管它可能不是最有效的)。

有很多方法可以编写这种类型的查询。例如,您可以使用EXISTS来避免在相关子查询中计数:

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) 
 ;
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用子查询或 CTE 和窗口聚合:

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 ;
Run Code Online (Sandbox Code Playgroud)

或者使用子查询查找出现多次的帐户,然后加入表:

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 ;
Run Code Online (Sandbox Code Playgroud)


小智 5

你也可以试试 withHAVING子句。

select account_id, count(id) as repetita
from t1
group by account_id

having count(id) > 1 ;
Run Code Online (Sandbox Code Playgroud)

该解决方案还记得你想要的字段添加到输出group by