【问题标题】:How to get a ActiveRecord count working with select如何使用 select 获得 ActiveRecord 计数
【发布时间】:2014-12-09 13:22:05
【问题描述】:

我有以下情况:

我有一个选择查询,我必须在选择中计算一个值。然后当我调用 any?count 时,它会导致 ActiveRecord::StatementInvalid Expection:

ActiveRecord::StatementInvalid: SQLite3::SQLException: near "*": syntax error: SELECT COUNT(foos.*, (foos.bar+1) as calculated) FROM "foos

我在一个看起来像这样的小测试中设置了这个:

require 'test_helper'

class FooTest < ActiveSupport::TestCase
  test 'any on active record relation' do
    foos = Foo.select('foos.*, (foos.bar+1) as calculated')
    assert(foos.any?, 'expected to work')
  end
end

好像是rails的问题:https://github.com/rails/rails/issues/15138 所以我的第一个想法是使用all 加载结果,但这不会影响任何事情。

顺便说一句。我正在使用 Rails 4.1

任何想法如何解决这个问题?

编辑:

我想这样做的原因如下:

我有一个包含长/纬度位置的模型。当我查询模型时,我计算到给定位置的距离并按距离对记录进行排序。所以我的查询看起来像这样:

nearest_records = MyModel
        .select("mymodels.*, 
             ST_Distance(mymodels.lnglat, #{user_location}) as distance")
        .order(distance).limit(6)

这非常有效。但现在在我看来,我想知道我的列表是否包含任何记录,所以我打电话给any?。这打破了所描述的漏洞。它是由上述错误引起的,因为any? 使用计数。

所以我的第一次尝试只是使用all 方法执行查询,但这并不能正常工作。我目前的解决方法是通过在 ActiveRecordRelation 上调用 each 来触发查询,然后在第一个元素处中断。

nearest_records.each { break }

但我真的不喜欢这种独奏。希望有人可以帮助我。

我正在使用 Rails 4.1.0

【问题讨论】:

  • 计数有问题。对我有吗?似乎工作。您使用哪个版本的导轨?我正在使用 4.1.8。
  • @Saravanan 感谢您的提示。我将 rails 更新到 4.1.8 版,现在可以使用了。似乎他们已经修复了任何?问题。使用 count 时,只需提供一个参数即可进行计数,例如 :all Foo.select('foos.*, (foos.bar+1) as calculated').count(:all) 有效。

标签: ruby-on-rails ruby activerecord


【解决方案1】:

这与您所链接的问题不同,我不会真正认为这是 Rails 的问题,因为不清楚您要实现什么。

any? 方法对符合特定条件的记录进行计数,如果计数不为零,则返回 true。将这个查询与上面的 select 结合起来是没有意义的,没有提供任何条件。

仅当您想从表中检索列的子集(或可能从另一个表中检索列)时,为 select 提供参数才有效。当你想统计多条记录时,只需要选择COUNT(id)或类似的,但Rails会自动完成。

如果您能详细解释一下您的代码应该做什么,它可能会有所帮助。

【讨论】:

    【解决方案2】:

    当你使用any? 时,Rails 会在COUNT 中包装 sql select 语句。 将selectany? 一起使用会导致错误的SQL 语句,因为您不能在COUNT 中使用多个列。

    此外,只对聚合函数或DISTINCT 进行计数才有意义。 例如,

    # count all records and count distinct 'bar' 
    Foo.select('count(*), count(distinct(bar))')
    # count all records and sum 'bar'
    Foo.select('count(*), sum(bar)')
    

    【讨论】:

      猜你喜欢
      • 2017-11-26
      • 1970-01-01
      • 2016-04-22
      • 2018-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多