删除存在引用关联的A、B表过期记录的SQL实现疑问
解决方法:分步删除关联表中符合条件的记录
你的问题核心是DELETE语句必须明确指定要删除的表——因为你的查询同时涉及A和B两个表,数据库没法自动判断你要删哪一个。我们可以分两步来完成操作,先处理关联的B表,再处理主表A:
第一步:删除B表中关联的过期记录
先用你已经验证过的查询逻辑,找出所有需要删除的A的ID,然后删除B表中这些ID对应的所有记录:
DELETE FROM B WHERE ID IN ( SELECT A.ID FROM A INNER JOIN B ON A.ID = B.ID GROUP BY A.ID HAVING Max(B.DateUpdated) <= Date() - 84 )
第二步:删除A表中对应的过期记录
复用同样的子查询定位要删除的A的ID,再删除A表的记录:
DELETE FROM A WHERE ID IN ( SELECT A.ID FROM A INNER JOIN B ON A.ID = B.ID GROUP BY A.ID HAVING Max(B.DateUpdated) <= Date() - 84 )
特殊情况处理(比如Access数据库)
有些数据库(比如Microsoft Access)不允许在DELETE的子查询中直接引用被删除的表,这时候可以把查询结果嵌套一层临时子查询绕开限制:
-- 删除B表 DELETE FROM B WHERE ID IN ( SELECT ID FROM ( SELECT A.ID FROM A INNER JOIN B ON A.ID = B.ID GROUP BY A.ID HAVING Max(B.DateUpdated) <= Date() - 84 ) AS TempTable ) -- 删除A表 DELETE FROM A WHERE ID IN ( SELECT ID FROM ( SELECT A.ID FROM A INNER JOIN B ON A.ID = B.ID GROUP BY A.ID HAVING Max(B.DateUpdated) <= Date() - 84 ) AS TempTable )
重要提醒
- 先备份数据! 删除操作是不可逆的,建议先把要删除的记录导出备份,或者在测试环境验证后再执行。
- 可以先单独运行子查询(
SELECT A.ID FROM ...)确认要删除的ID数量和正确性,再执行DELETE。 - 如果你的数据库支持事务(比如SQL Server、MySQL),可以把两个DELETE放在事务里,确保要么都成功,要么都回滚,避免数据不一致。
内容的提问来源于stack exchange,提问作者user9866087
相关产品推荐
相关产品推荐

