用NOT EXISTS改写NOT IN删除语句:三种写法是否正确等价?
用NOT EXISTS改写DELETE语句的正确性分析
原DELETE语句(使用NOT IN):
DELETE FROM stage_instance WHERE binary_id NOT IN (SELECT id FROM stage_binary)
以下是对三种写法的正确性与等价性分析:
写法一
DELETE FROM stage_instance WHERE NOT EXISTS (SELECT 1 FROM stage_binary JOIN stage_instance ON stage_instance.binary_id = stage_binary.id)
完全错误,和原语句逻辑完全不符。子查询通过JOIN关联两张表,只要两张表存在任意一对匹配的行,子查询就会返回结果,NOT EXISTS就会为假,最终会删除0行;只有当两张表完全没有匹配行时,才会删除所有stage_instance的行。
写法二
DELETE FROM stage_instance WHERE NOT EXISTS (SELECT 1 FROM stage_binary, stage_instance WHERE stage_instance.binary_id = stage_binary.id)
这是写法一的隐式JOIN版本,同样错误。逻辑和写法一完全一致,无法正确过滤出binary_id不在stage_binary.id中的行。
写法三
DELETE FROM stage_instance WHERE NOT EXISTS (SELECT 1 FROM stage_binary WHERE stage_instance.binary_id = stage_binary.id)
正确且等价于原NOT IN语句。这是你所说的相关子查询,会针对stage_instance的每一行,检查该行的binary_id是否在stage_binary.id中存在:如果不存在,NOT EXISTS为真,该行会被删除,和原语句逻辑完全匹配。
你对相关子查询的判断是准确的:写法三是相关子查询(子查询引用了外部查询的stage_instance.binary_id字段,每一行都要执行一次子查询),而写法一和写法二的子查询是独立的,不依赖外部查询字段,仅执行一次就得到结果。
内容的提问来源于stack exchange,提问作者moth
相关产品推荐
相关产品推荐

