LeetCode 196删除重复邮件问题:DELETE多表语法适用场景与表连接类型疑问
关于LeetCode 196题DELETE语法的两个疑问解答
嘿,这个问题问得很精准,我来给你理清楚这两个点:
1. 哪些场景适合用DELETE p1 FROM p1, p2这类语法?
这是多表DELETE的一种写法,主要在MySQL(以及MariaDB这类兼容MySQL语法的数据库)中支持,适合的场景是:
- 你需要基于其他表(或同表的其他行)的条件来删除某一张表的记录,而不是只靠单表字段过滤。
- 比如这个LeetCode题的场景:要删除重复邮箱里ID较大的记录,必须把同一张表的两行做对比(邮箱相同、ID更大的那行要删),这时候就需要同时引用两次Person表,然后明确指定删除其中一个别名对应的行。
举个更直白的例子:如果要删除所有属于已注销用户的订单,就可以这么写:
DELETE o FROM Orders o, Users u WHERE o.user_id = u.id AND u.status = 'deleted';
这里的核心是:DELETE后面指定的是你要删除的目标表的别名,FROM后面列出所有需要关联的表,WHERE里写关联和过滤条件。
⚠️ 注意:不是所有数据库都支持这种语法,比如PostgreSQL用的是DELETE FROM ... USING ...的写法,SQL Server也有自己的多表DELETE语法,所以这种逗号分隔的多表DELETE主要是MySQL生态下常用。
2. Person p1, Person p2是自连接还是交叉连接?
本质上是交叉连接(CROSS JOIN),但加上WHERE p1.Email = p2.Email的条件后,它就变成了等值自连接。
- 交叉连接的定义是:把两个表的所有行做笛卡尔积,也就是每个p1的行都和所有p2的行配对。
- 但这里的
WHERE条件过滤掉了邮箱不匹配的行对,最终只保留了邮箱相同的行,这就实现了自连接的效果——把表和自己关联起来,找到重复的邮箱记录。
现在更推荐用显式的INNER JOIN写法,可读性更强,和原语句功能完全一致:
DELETE p1 FROM Person p1 INNER JOIN Person p2 ON p1.Email = p2.Email WHERE p1.Id > p2.Id;
原语句的逗号写法是SQL早期的语法风格,虽然功能没问题,但显式JOIN的写法更清晰,也符合现代SQL的编码规范。
内容的提问来源于stack exchange,提问作者Gao Yuxiang
相关产品推荐
相关产品推荐

