如何通过左外连接删除table1中关联table2的sname为空的数据?
嘿,我来帮你理清楚这个问题~ 先从左外连接的原理讲起,再给你对应的删除方案,保证你能搞明白!
解决思路与左外连接原理说明
一、先搞懂左外连接(LEFT JOIN)的基本原理
左外连接的逻辑其实很直白:
- 以**左表(这里是table1)**为核心,保留左表的每一行数据
- 尝试把左表的行和右表(table2)中满足关联条件(这里是
table1.anum = table2.anum)的行做匹配 - 如果右表找不到匹配的行,右表的所有列会自动填充为
NULL;如果右表有多个匹配行,左表的该行会被复制多次,分别对应右表的每个匹配项
拿你的表数据举个实际例子,执行左连接的SQL:
SELECT t1.*, t2.sname FROM table1 t1 LEFT JOIN table2 t2 ON t1.anum = t2.anum;
得到的结果会是这样:
| anum | pnum | sname |
|---|---|---|
| 001 | 001 | 'cooking' |
| 001 | 001 | 'cleaning' |
| 002 | 001 | 'teaching' |
| 003 | 002 | NULL |
| 004 | 002 | NULL |
你能看到:
- table1的
anum=001对应table2的两行,所以结果里会出现两次 - table1的
anum=003对应table2中anum=003且sname=NULL的行,所以sname显示NULL - table1的
anum=004在table2里找不到匹配的anum,所以sname也显示NULL
二、实现删除需求的SQL语句
你的需求是删除table1中关联的table2里sname为NULL的数据,这里分两种常见场景,你可以根据实际需求选:
场景1:仅删除存在table2关联且sname为NULL的行
也就是只删table1中anum=003的行(因为它对应table2里明确有sname为NULL的记录),可以用两种方式实现:
方式1:子查询写法
DELETE FROM table1 WHERE anum IN ( SELECT anum FROM table2 WHERE sname IS NULL );
这个语句先从table2里找出所有sname=NULL的anum,再删除table1中这些anum对应的行。
方式2:JOIN写法
DELETE t1 FROM table1 t1 JOIN table2 t2 ON t1.anum = t2.anum WHERE t2.sname IS NULL;
这里用内连接直接匹配table1和table2中anum相同且sname=NULL的行,然后删除table1的对应记录。
场景2:删除所有左连接后sname为NULL的行
如果你要删的是table1中要么没有table2匹配,要么匹配到的table2行sname为NULL的行(也就是anum=003和anum=004的行),可以这样写:
DELETE t1 FROM table1 t1 LEFT JOIN table2 t2 ON t1.anum = t2.anum WHERE t2.sname IS NULL;
这里用左连接保留table1的所有行,筛选出t2.sname=NULL的行后,删除对应的table1记录。
三、避坑建议
执行删除前,强烈建议先把DELETE换成SELECT预览要删除的行,确认无误后再执行删除操作:
比如针对场景2,先执行:
SELECT t1.* FROM table1 t1 LEFT JOIN table2 t2 ON t1.anum = t2.anum WHERE t2.sname IS NULL;
看看结果是不是你想要删除的内容,避免误删数据~
内容的提问来源于stack exchange,提问作者Tyrionus
相关产品推荐
相关产品推荐

