社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  DATABASE

多列MySQL内部联接

wwl • 6 年前 • 1486 次点击  

假设我叫了下表 Email ,在哪里 Id 是主键:

+----+------------------+
| Id | Email            |
+----+------------------+
| 1  | anne@example.com |
| 2  | cat@example.com  |
| 3  | anne@example.com |
+----+------------------+

我正在尝试删除除第一个之外的所有重复项。因此,在这种情况下,所需的输出将是

+----+------------------+
| Id | Email            |
+----+------------------+
| 1  | anne@example.com |
| 2  | cat@example.com  |
+----+------------------+

在问了一个朋友之后,我发现这个解决方案是有效的:

DELETE t1 FROM Person t1 INNER JOIN Person t2
Where t1.Email=t2.Email and t1.Id > t2.Id

我的问题是为什么这样做有效?尤其是当 t1 内连 t2 电子邮件 字段,程序如何知道 anne@example.com 应该与哪个匹配,因为这个值有多个不同的ID?

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/38928
 
1486 次点击  
文章 [ 3 ]  |  最新文章 6 年前
nbk
Reply   •   1 楼
nbk    6 年前

比较两个相同的表,并检查两个表的emailAddress相同的所有情况。

如果ID相同,则忽略该行。

如果 ID不同 必须有身份证 比第一次出现的ID大 ,此行将被删除。

Gordon Linoff
Reply   •   2 楼
Gordon Linoff    6 年前

首先,这通常是使用聚合编写的:

DELETE p
    FROM Person p INNER JOIN
         (SELECT p2.email, MIN(p2.id) as min_id
          FROM Person p2
          GROUP BY p2.email
         ) p2
         ON p.email = p2.email and p.id > p2.min_id;

为什么你的版本有效?好吧,这是因为 join 不仅匹配数据,而且过滤数据。

所以,情况

t1.Email = t2.Email and t1.Id > t2.Id

对每一张唱片都这么说 t1 在t2中查找匹配的记录,其中 t1.id > t2.id . 也就是说,在 t1 有匹配的记录 较小 id .

所有记录都有这个属性——除了每个电子邮件有一个。那将是ID最小的记录。

我不建议使用这种方法来识别最小的记录,因为 参加 乘以记录数。如果一封电子邮件有五个记录,那么其中一个记录最多有四个匹配项。当你说要删除一个记录四次时,MySQL需要弄清楚该怎么做。(当然,这是正确的做法,但还有额外的工作。)

聚合方法没有类似的问题。

Barbaros Özhan
Reply   •   3 楼
Barbaros Özhan    6 年前

只考虑按电子邮件列之间的相等性筛选此select语句

SELECT t1.*, t2.* 
  FROM Person t1 
 INNER JOIN Person t2
 WHERE t1.Email=t2.Email 
 ORDER BY t1.Id, t2.Id;

退货 (1,1), (1,3), (3,1), (3,3) 对于邮件,分别为T1.ID和T2.ID值 anne@example.com ,而且只有 (2,2) 对于 cat@example.com 。如果你考虑另一个过滤器 AND t1.Id > t2.Id ,

SELECT t1.*, t2.* 
  FROM Person t1 
 INNER JOIN Person t2
 WHERE t1.Email=t2.Email 
   AND t1.id > t2.id
 ORDER BY t1.Id, t2.Id;

那你就只有一个元组了 (3,1) 自从 t1.id > t2.id 只满足ID元组的这种情况。如果你转换 SELECT t1.*, t2.* DELETE t1 (当然,删除 ORDER BY 第二部分),显然你会删除 id = 3 以及具有ID值的左行 1 2 ,如果您替换 选择T1.*和T2.* 具有 DELETE t2 ,那么您将拥有具有ID值的行 3 .

Demo