这既是其他的答案几乎合成。
第一:坚持has_many through
@TheChamp建议。你可能已经在使用它,只是忘了写它,否则它不会工作。那么,你已经受到警告。
我一般尽我所能避免我的查询中的原始SQL。我上面提供的select
提示产生了一个工作解决方案,但是会做一些不需要的东西,比如join
,如果没有实际需要的话。所以,让我们避免戳一个关联。这次不行。
这里谈到为什么我在许多-to-many关联宁愿has_many through
到has_and_belongs_to_many
的原因:我们可以查询加盟模式本身没有原始SQL:
WorkerMembership.select(:worker_id).where(event: @event)
这不是结果还没有,但它可以让我们我们不想要的worker_id
的列表。然后,我们只是包装此查询到“给我所有,但这些家伙”:
Worker.where.not(id: <...>)
所以最终的查询是:
Worker.where.not(id: WorkerMembership.select(:worker_id).where(event: @event))
,并将其输出单个查询(上@event
与id
等于1
):
SELECT `workers`.* FROM `workers` WHERE (`workers`.`id` NOT IN (SELECT `worker_memberships`.`worker_id` FROM `worker_memberships` WHERE `worker_memberships`.`event_id` = 1))
我也给信贷@apneadiving他的解决方案和有关mysql2
的提示。 SQLite的explain
是可怕的!我的解决方案,如果我正确阅读explain
的结果,就像@ apneadiving一样。
@TheChamp还为所有答案的查询提供了性能成本。查看比较评论。
有趣! :) – apneadiving 2014-10-31 12:39:31
你会介意分担两者的费用吗?只是好奇心 – apneadiving 2014-10-31 12:40:48
@apneadiving肯定的事情:http://pastebin.com/BupHkLQf(一定要打开文字包装,'解释'表很长) – 2014-10-31 12:52:27