如何在where条件下检测sql中的重复行

axkjgtzd  于 2021-06-21  发布在  Mysql
关注(0)|答案(4)|浏览(401)

我有一个包含以下示例数据的表:

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“这在同一个地方重复。
谢谢。

laik7k3q

laik7k3q1#

你可以用简单的 GROUP BY 带的子句 HAVING 子句来过滤出唯一的地方

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

eqqqjvef2#

你可以用开窗的 COUNT(*) 支持现代rdbms。

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

dbfiddle演示
sql服务器/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演示

xn1cxnb4

xn1cxnb43#

非常感谢,我尝试了gordon linoff的第一个解决方案,结果成功了。但是我有一个小问题,我有一个“where”子句,这个:

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

显示与以下相同的结果:

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

因为这是一个or条件,但我不知道如何修复,在第一个查询中,如何只显示所有这些地方的项,而不是其中两个。

lfapxunr

lfapxunr4#

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

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;

相关问题