如何选择具有字段重复值的每一行

Posted

技术标签:

【中文标题】如何选择具有字段重复值的每一行【英文标题】:How to SELECT every row that has a duplicate value of a field 【发布时间】:2017-04-18 13:59:41 【问题描述】:

使用 PostgreSQL,我试图找到一种方法来选择 每一 行,该行与特定列的值重复。

例如,我的表格如下所示:

id   | username | email
1    | abc      | abc@test.com
2    | abc1     | abc@test.com
3    | def      | def@test.com
4    | ghi      | ghi@test.com
5    | ghi1     | ghi@test.com

我想要的输出将选择用户名和电子邮件,其中电子邮件计数 > 2:

abc   | abc@test.com
abc1  | abc@test.com
ghi   | ghi@test.com
ghi1  | ghi@test.com

我尝试过group by having,这让我接近了我想要的,但我不认为我想使用group by,因为这实际上会将行与重复值组合在一起,我仍然想显示包含重复值的单独行。

SELECT email FROM auth_user
GROUP BY email HAVING count(*) > 1;

这只会显示具有重复值的电子邮件:

abc@test.com
ghi@test.com

我可以使用SELECT email, count(*) FROM ... 将计数包含在其中,但这也不是我想要的。

我想我想要where count(email) > 1 之类的东西,但这给了我一个错误,说ERROR: aggregate functions are not allowed in WHERE

如何在不分组的情况下选择重复值?

使用解决方案更新

@GordonLinoff 发布了正确答案。但是为了满足我仅获取用户名和电子邮件字段的确切需求,我对他进行了一些修改(这应该是不言自明的,但发布以防其他人需要确切的查询)

select username, email
from (select username, email, count(*) 
      over (partition by email) as cnt
      from auth_user au
) au
where cnt > 1;

【问题讨论】:

【参考方案1】:

如果你想要所有原始行,那么我建议使用count(*) 作为窗口函数:

select au.*
from (select au.*, count(*) over (partition by email) as cnt
      from auth_user au
     ) au
where cnt > 1;

【讨论】:

我喜欢你在我发布问题后 5 秒内回答的方式。我想我需要更多地研究我的 SQL。我会在 11 分钟后接受你的回答。谢谢!【参考方案2】:

您可能会发现这也很有帮助:

select t1.*, t2.*
from auth_user t1, auth_user t2
where t1.id != t2.id
and t1.email = t2.email

【讨论】:

以上是关于如何选择具有字段重复值的每一行的主要内容,如果未能解决你的问题,请参考以下文章

如何在R中的一列中添加具有不同值的新行

DQL选择具有一列MAX值的每一行

如何在使用存储过程时创建具有自动增量的 id 字段?

选择具有多个重复字段值的行

Wtforms:如何使用具有动态选择值的选择字段生成空白值

如何在 MySQL 中选择字段具有最小值的数据?