【问题标题】:rails/activerecord: how to get SQL COUNT and SUM to work with Postgres (at heroku)rails/activerecord:如何让 SQL COUNT 和 SUM 与 Postgres 一起工作(在 heroku)
【发布时间】:2012-02-05 11:50:26
【问题描述】:

我的 rails 3 应用程序需要使用 SELECT DISTINCT,这(据我所知)无法通过 activerecord 查询来完成。所以我一直在执行直接 SQL,它在 sqllite 上本地运行良好——但在 Heroku (postgres) 上失败了。

在我的本地 (sqllite) 应用程序中,这工作正常:

r = ActiveRecord::Base.connection.execute("my query string")

但是在 heroku 上,使用 ActiveRecord::Base.connection.execute 总是返回一个空数据集

#<PGresult:0x0000000xxxxxxxxx>

即使是非常简单的查询,例如

r = ActiveRecord::Base.connection.execute("SELECT numeric_score  FROM beeps WHERE store_id = '132' AND survey_num = '2'")

所以我使用heroku console 来调试一些非常基本的 SQL 查询,以尝试了解如何重新格式化我的 SQL 以在 Heroku/Postgres 上工作。

SELECT column_name WORKS:heroku 控制台,选择 postgres 记录是没有问题的,例如这个工作正常:

n = Beep.find_by_sql("SELECT numeric_score  FROM beeps WHERE store_id = '132' AND survey_num = '2'")

给出预期的三个值:

[#<Beep numeric_score: 10>, #<Beep numeric_score: 9>, #<Beep numeric_score: 8>]

但是SELECT COUNT 失败了??当我尝试在 SQL 中对它们进行计数时

n = Beep.find_by_sql("SELECT COUNT(*)  FROM beeps WHERE store_id = '132' AND survey_num = '2'")

它失败了,给出:

[#<Beep >]

SELECT SUM(column) 也失败了??当我尝试对它们求和时

n = Beep.find_by_sql("SELECT SUM(numeric_score)  FROM beeps WHERE store_id = '132' AND survey_num = '2'")

它也失败了,给出:

[#<Beep >]

如何使用 Postgres 执行直接 SQL...SUM(columnname) 和 COUNT(*) 应该可以工作,对吧?

【问题讨论】:

  • 原始 SQL 肯定可以工作。 SUM()COUNT() 很好。您可能需要为列命名,例如:COUNT(*) AS ct。此外,如果store_id 是整数值,则只需写store_id = 132survey_num 也一样。没有单引号,那些是字符串值。查询仍然有效,因为在这种情况下字符串会自动转换为整数。

标签: sql postgresql heroku


【解决方案1】:

这里有几件事。

首先,find_by_sql 将根据返回的数据返回已初始化的对象,这就是为什么您没有从计数中看到任何返回的原因。

为了使用 AR 做到这一点,您可以这样做:

Beep.where(:store_id => 123).where(:survey_num => 2).count
=> 5

这将返回一个数字。和 sum 也是一样的:

Beep.where(:store_id => 123).where(:survey_num => 2).sum(:numeric_score)
=> 5

您也可以对 AR 使用区分,但它不是那么干净:

Beep.select("DISTINCT *").where(:store_id => 123).where(:survey_num => 2)
=> [<Beep>, <Beep>...etc]

为了直接查询数据库,这仍然是可能的,你几乎在那里:

conn = ActiveRecord::Base.connection
sql = "SELECT DISTINCT * FROM beeps WHERE store_ID = 123"
res = conn.execute sql

# res is now a PGResult object

res.each do |row|
  puts row["id"]
  puts row["numeric_score"]
end

【讨论】:

  • 非常感谢。这正是我所需要的。有了像你这样的成员,SO 社区就变得非凡了。
【解决方案2】:

有一个 uniq 方法可以添加到 ActiveRecord 关系中,将 DISTINCT 添加到 SELECT

Beep.where(:store_id => 123).where(:survey_num => 2).uniq

另请参阅:http://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-uniq

【讨论】:

    猜你喜欢
    • 2013-10-25
    • 2013-11-08
    • 1970-01-01
    • 1970-01-01
    • 2013-11-30
    • 2010-09-11
    • 1970-01-01
    • 1970-01-01
    • 2015-02-12
    相关资源
    最近更新 更多