您可以使用嵌套子查询来做到这一点,这是一种可行的解决方案,但不一定是有效的解决方案,因此您必须运行一些基准测试。
以下涉及在A
和之间的 join_table 上执行的三个嵌套查询B
。您首先确定所有不是or的 id B
(称为这些) 。然后,您确定哪些与这些有关系并调用它们。所有不在其中的 's正是我们想要的(称它们为)。一旦你刚刚查询了表。excluded_bs
B1
B2
A
excluded_bs
excluded_as
A
excluded_as
included_as
included_as
A
excluded_bs = %(SELECT B_id FROM join_table WHERE B_id NOT IN (:included_bs))
excluded_as = %(SELECT A_id FROM join_table WHERE B_id IN (#{excluded_bs}))
included_as = %(SELECT A_id FROM join_table WHERE A_id NOT IN (#{excluded_as}))
A.where("id IN (included_as)", :included_bs => [B1.id, B2.id])
这应该为您提供与 和 有关系的所有' A
s ,但不与任何其他人有关系。您可能可以稍微清理一下并使其更有效率,但它至少应该可以工作。B1
B2
编辑:
哎呀!要修剪那些只有B1
orB2
的部分,请尝试GROUP BY
. 将最后一个子查询更改为
included_as = %(SELECT A_id, COUNT(*) as Total FROM join_table WHERE A_id NOT IN (#{excluded_as}) GROUP BY A_id HAVING Total = :count)
和主要查询
Bs = [B1, B2]
A.where("id IN (SELECT A_id FROM (#{included_as}))", :included_bs => Bs.map(&:id), :count => Bs.count)