mysql - Ruby/Rails 使用 MySQL 中的计算列对范围内的对象进行计数

标签 mysql ruby-on-rails ruby scope

我不知道如何正确计算范围内的对象。

对于此示例,我们假设产品(“skus”)有纬度和经度,用户也有。

我有一个有效的 find_by_sql 示例:

  def self.with_max_distance(user, distance)
    Sku.find_by_sql(
    <<-eos
      SELECT *,
      ( 3959 * acos( cos( radians(#{user.lat}) ) * cos( radians( skus.lat ) )
      * cos( radians(skus.lng) - radians(#{user.lng})) + sin(radians(#{user.lat}))
      * sin( radians(skus.lat)))) AS distance
      FROM skus
      HAVING distance < #{distance}
    eos
    )
  end

我能够使以下范围部分工作:

  scope :scope_with_max_distance, lambda { |user, distance|
    { :select => "skus.*, ( 3959 * acos( cos( radians(#{user.lat}) ) * cos( radians( skus.lat ) ) * cos( radians(skus.lng) - radians(#{user.lng})) + sin(radians(#{user.lat})) * sin( radians(skus.lat)))) AS distance",
      :having => "distance < #{distance}"
    }
  }

该范围似乎可以正确获取对象,尽管我没有对其进行广泛测试,但如果我将其与其他范围链接起来,它似乎可以工作。

但是,我无法count()对象,这真的很烦人。我知道我可以使用 length(),但它不适用于 count,这一事实让我想知道是否有更好的方法来做到这一点。

1.9.3p125 :048 > Sku.scope_with_max_distance(User.first, 50).limit(10).count
  User Load (0.5ms)  SELECT `users`.* FROM `users` LIMIT 1
   (0.6ms)  SELECT COUNT(count_column) FROM (SELECT 1 AS count_column FROM `skus` HAVING distance < 50 LIMIT 10) subquery_for_count 
ActiveRecord::StatementInvalid: Mysql2::Error: Unknown column 'distance' in 'having clause': SELECT COUNT(count_column) FROM (SELECT  1 AS count_column FROM `skus`  HAVING distance < 50 LIMIT 10) subquery_for_count 

我真的很感激任何建议或想法 - 我尝试了许多不同的方法,但一直无法找到一种完全有效的方法。如果问题需要更多说明,请告诉我。

最佳答案

count 将用尽可能高效地构建计数所需的简单元素替换您的 select。它不会检查其他约束来确保 SQL 有效。您可以将 having 中的 distance 别名替换为您选择的公式来解决此问题。另外,我建议您将 having 替换为 where 以避免不可数据库移植的隐式分组:

scope :scope_with_max_distance, lambda { |user, distance|
  distance_formula = "(3959 * acos( cos( radians(#{user.lat}) ) * cos( radians( skus.lat ) ) * cos( radians(skus.lng) - radians(#{user.lng})) + sin(radians(#{user.lat})) * sin( radians(skus.lat))))"
  { :select => "skus.*, #{distance_formula} AS distance",
    :where => "#{distance_formula} < #{distance}"
  }
}

最后一件事,您在 limit(10) 之后调用 count 这意味着 count 永远不会大于 10。这本质上并不是错误的,但我'我不确定这是否是您想要做的。

关于mysql - Ruby/Rails 使用 MySQL 中的计算列对范围内的对象进行计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14025720/

相关文章:

ruby-on-rails - 对 Gutentag 标签进行搜查 - 未定义方法 `type' for nil :NilClass

ruby-on-rails - 迪尔德 : Symbol not found: _rb_thread_select

PHP 和 SQL - 如何选择当年所有月份的最高总和?

php - 上载多个图像并将其路径存储在数据库中

ruby-on-rails - Ruby 测试 : block vs. 方法

ruby-on-rails - 保存失败后 Rails 不回滚事务()

ruby - 在 ruby​​ 中仅在单例中实例化对象一次

ruby-on-rails - 为什么在引用类时会出现 "uninitialized constant"错误?

mysql - eloquent,用外表数据检索用户数据

java - 连接到数据库的方法给出空指针异常