计算字段不等于值X的记录

时间:2013-03-06 21:37:20

标签: ruby-on-rails ruby-on-rails-3 postgresql activerecord

我正在尝试对字段不等于特定值的结果执行计数,但它总是无法返回结果。

例如,假设公司产品具有一对多关系,我可能会通过查询从ActiveRecord获取以下数组Company.find(63).products(这将是SELECT "products".* FROM "products" WHERE "products"."company_id" = 63;的SQL等价物):

<Product id: 1, company_id: 63, foo_id: 1>,
<Product id: 2, company_id: 63, foo_id: 3>,
<Product id: 3, company_id: 63, foo_id: nil>, 
<Product id: 4, company_id: 63, foo_id: nil>

但是,如果我尝试扩展上述查询来计算除第一条记录以外的所有内容:

Company.find(63).products.where("foo_id != ?", 1).count

在SQL中是:

SELECT COUNT(*) FROM "products" WHERE "products"."company_id" = 63 AND (foo_id != 1)

当我希望看到 3 时,我似乎总是得到 1 。为什么会发生这种情况?如何才能正确计算?

3 个答案:

答案 0 :(得分:1)

如果你说你应该得到1而不是0.你要找的是DISTINCT FROM作为=而{null}类型的!=都会返回未知结果。

SELECT COUNT(*) FROM 
products 
WHERE products.company_id = 63 AND (foo_id IS DISTINCT FROM 1)

http://sqlfiddle.com/#!1/8b7a0/3

至于进一步的信息。 DISTINCT FROM是PostgreSQL独有的,所以这样做的标准版本是:

SELECT COUNT(*) FROM 
products
WHERE products.company_id = 63 AND (foo_id<>1 OR foo_id IS NULL)

答案 1 :(得分:0)

您是否尝试过使用<>代替!=

<>

答案 2 :(得分:0)

Company.find(63).products.where("foo_id != ?", 1).count

应该是

Company.find(63).products.where("foo_id <> ?", 1).count

但你应该更进一步:

class Product
  def self.not_foo(foo_id)
    where("foo_id <> ?", foo_id)
  end
end

现在

 Company.find(63).products.not_foo(1).count