查找不在联接中的记录 - 有效

时间:2012-03-21 20:07:19

标签: mysql sql ruby-on-rails-3

我已经看过几次这个问题了,但所有的答案都依赖于小数据集或有限的关联,所以这里再说一次。

我有一个has_many_through关系

class ModelA
  has_many :model_c, :through => :model_b
  has_many :model_b

class ModelB
  belongs_to :model_a
  belongs_to :model_b

class ModelC
  has_many :model_a, :through => :model_b
  has_many :model_b

我需要清理“孤立的”模型B和模型C - 其中模型A已被删除。因此,我需要在没有模型A的情况下找到并删除模型B,然后在没有模型B的情况下找到模型C.

我们在删除模型A时没有这样做,因为一个模型A可以与成千上万的模型C相关联并且花费的时间太长了 - 我们使用依赖的破坏与一个防护块一起开火了很多查询并且花了太长时间。我们现在打算做一个夜间清理工作。

因此,我需要找到并删除所有ModelB,其model_a列包含现在不存在的模型A的ID,并删除它们。

到目前为止我发现的解决方案对我不起作用(因为我们可能在给定时间内有成千上万的孤​​儿): - 从ModelA.id和ModelB.model_a加载所有ID并进行设置差异 - 从ModelA.id加载所有ID并传递给Model B上的“NOT IN”查询 - 从模型C逐个记录检查

此时,我认为我需要一个直接的SQL解决方案(我很好),但我不太确定我在寻找什么。

(DB是MySQL)

1 个答案:

答案 0 :(得分:3)

我没有测试过,但我相信如果理解MySQL Multiple-table Delete Syntax

,这将会有效
DELETE 
     ModelC, 
      ModelB 
FROM ModelC 
     LEFT JOIN ModelB 
     ON ModelC.BID = ModelB.BID
     LEFT JOIN ModelA
     ON ModelB.AID = ModelA.AID
WHERE
     ModelB.BID is NULL
     OR ModelA.AID IS NULL