如何在SQL中检测具有条件的重复行

时间:2018-04-21 12:20:45

标签: mysql sql

我有一张包含此示例数据的表格:

place_id    email
----------------------------
   3        uno@uno.com
   3        dos@dos.com
   4        tres@tres.com
   5        uno@uno.com
   6        uno@uno.com
   3        dos@dos.com
   4        tres@tres.com

我想要显示位于不同位置的电子邮件,我尝试了此查询:

select email, count(email)
from table
group by email
having count(email) > 1

问题是,这显示了同一个地方的重复行,我只需要在不同的地方显示行。例如,只显示电子邮件" uno@uno.com" ;,位于3,5和6的地方,而不是" dos@dos.com"在同一个地方重复。

感谢。

4 个答案:

答案 0 :(得分:0)

您可以使用现代RDBMS支持的窗口COUNT(*)

SELECT *
FROM (SELECT t.*, COUNT(DISTINCT place_id) OVER(PARTITION BY email) AS cnt
      FROM tab t) sub
WHERE cnt > 1

<强> DBFiddle Demo

SQL Sever / MariaDB / MySQL 8.0 / PostgreSQL:

SELECT *
FROM (SELECT *, COUNT(*) OVER(PARTITION BY email) AS cnt
      FROM (SELECT DISTINCT place_id, email FROM tab) s
      )sub
WHERE cnt > 1;

<强> DB-Fiddle.com Demo

答案 1 :(得分:0)

如果您只想要电子邮件,可以使用聚合:

select email
from t
group by email
having min(place) <> max(place);

如果您希望这些地方也在一个唯一的列表中,您可以这样做:

select distinct place, email
from t
where exists (select 1
              from t t2
              where t2.email = t.email and t2.place <> t.place
             );

而且,尽管您可以使用窗口函数,但解决方案并不那么明显:

select distinct place, email
from (select t.*,
             min(t.place) over (partition by t.email) as min_place,
             max(t.place) over (partition by t.email) as max_place
      from t
     ) t
where min_place <> max_place;

答案 2 :(得分:0)

您可以使用带GROUP BY子句的简单HAVING子句来过滤掉唯一的地方

select place_id, email
from table t
group by place_id, email 
having count(*) = 1;

答案 3 :(得分:0)

非常感谢,我尝试了Gordon Linoff的第一个解决方案,并且它已经奏效了。但我有一点问题,我有一个&#34;其中&#34;条款,这:

Effect[IO]

显示与以下相同的结果:

select email, count(email) from data where place = 2 or place=3 or place=4 group by email having min(place) <> max(place)

因为它是一个或一个条件,但我不知道如何修复,并且在第一个查询中如何仅显示所有这些地方的项目,而不仅仅是其中两个。< / p>