Ruby on rails 如何选择不存在子项的记录
在rails中,我有两个表:Ruby on rails 如何选择不存在子项的记录,ruby-on-rails,activerecord,Ruby On Rails,Activerecord,在rails中,我有两个表: bans(ban_id, admin_id) ban_reasons(ban_reason_id, ban_id, reason_id) 我想查找某个管理员的所有ban,其中ban\u原因表中没有记录。我如何在Rails中做到这一点,而不必遍历所有ban记录并过滤掉所有带有ban.ban\u reasons.nil的记录?我希望使用一条SQL语句来实现这一点 我只需要做:(但我想用“rails”的方式) ActiveRecord只能让您了解到一点,之后的一切都应该
bans(ban_id, admin_id)
ban_reasons(ban_reason_id, ban_id, reason_id)
我想查找某个管理员的所有ban
,其中ban\u原因
表中没有记录。我如何在Rails中做到这一点,而不必遍历所有ban记录并过滤掉所有带有ban.ban\u reasons.nil的记录?
我希望使用一条SQL语句来实现这一点
我只需要做:(但我想用“rails”的方式)
ActiveRecord只能让您了解到一点,之后的一切都应该由原始SQL完成。AR的好处在于它使做这类事情变得非常容易 然而,自从Rails3以来,您几乎可以用ARELAPI做任何事情,尽管原始SQL看起来可能更可读,也可能不可读 我将使用原始SQL,如果您的查询性能不好,您可以尝试另一个查询:
SELECT b.*
FROM bans b
LEFT JOIN ban_reason br on b.ban_id = br.ban_id
WHERE br.ban_reason_id IS NULL
您的解决方案非常有效(只有一个请求),但它几乎是纯SQL:
bans = Ban.where("bans.id NOT IN (SELECT ban_id from ban_reason)")
您还可以尝试以下操作,并让rails完成部分工作:
bans = Ban.where("bans.id NOT IN (?)", BanReason.select(:ban_id).map(&:ban_id).uniq)
使用gem(我是其作者):
两者之间有什么性能差异吗?第二个会导致更多的查询吗?是的,第二个会导致更多的查询…我认为性能问题实际上取决于您的数据库大小。我猜如果目标是使用Rails,无论代价如何,那么这个建议是可行的,但是,对于大型数据集来说,性能将受到可怕的影响。在大多数数据库上,这将比上面的另一个数据库性能更好。许多数据库的性能相当差(他们计算出了集合)。这对于在连接上搜索空值也会有一定的性能影响,但我仍然认为它可能比上面的更好。我认为将其实现为notexists()将是此查询更自然的语法,但我认为SQL是正确的。
bans = Ban.where("bans.id NOT IN (?)", BanReason.select(:ban_id).map(&:ban_id).uniq)
Ban.where(admin_id: 123).where_not_exists(:ban_reasons)