Py学习  »  DATABASE

多列MySQL内部联接

wwl • 5 年前 • 1457 次点击  

假设我叫了下表 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
 
1457 次点击  
文章 [ 3 ]  |  最新文章 5 年前
nbk
Reply   •   1 楼
nbk    5 年前

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

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

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

Gordon Linoff
Reply   •   2 楼
Gordon Linoff    5 年前

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

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    5 年前

只考虑按电子邮件列之间的相等性筛选此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