13

我有一个客户模型和一个产品模型,其中一个客户有很多产品,一个产品属于一个客户。

我需要找到一个查询,如果他们在产品表中有记录,则只返回客户

客户表

id |      name
--------------
 1 | Company A
 2 | Company B
 3 | Company C

产品表

id |      name |  client_id
---------------------------
 1 | Product A |         1
 2 | Product B |         1
 3 | Product C |         3
 4 | Product D |         3
 5 | Product E |         1

我只需要客户 1 3

例如像

@clients = Client.where("client exists in products")  #something to this effect
4

4 回答 4

23

最简单但不是最快的:

Client.where(:id => Product.select(:client_id).map(&:client_id))

SQL 子查询(更快):

Client.where("EXISTS(SELECT 1 from products where clients.id = products.client_id)")
于 2013-01-07T06:13:55.007 回答
7

这是另一个解决方案。这是一个类似于 Valery 的第二个解决方案的子查询,但没有写出 sql:

Client.where(Product.where(client_id: Client.arel_table[:id]).exists)
于 2015-07-28T18:34:20.063 回答
6

这是使用Where Exists gem 的解决方案(披露:我是它的作者):

Client.where_exists(:products)
于 2015-08-30T18:53:59.120 回答
1

另一个存在的宝石:activerecord_where_assoc(我是作者)

用它:

Client.where_assoc_exists(:products)

如果你还必须指定一些产品,你什么时候可以这样做:

Client.where_assoc_exists(:products, id: my_products.map(&:id))

在没有宝石的情况下这样做很容易出错。

在文档中阅读更多内容。这里有一个介绍例子

于 2020-02-09T17:29:53.713 回答