rails / activerecord: как заставить SQL COUNT и SUM работать с Postgres (на heroku) - PullRequest
0 голосов
/ 05 февраля 2012

Моему приложению rails 3 необходимо использовать SELECT DISTINCT, что (насколько я знаю) не может быть выполнено с запросами activerecord. Итак, я выполняю прямой SQL, и он нормально работает локально на sqllite - но он не работает в Heroku (postgres).

В моем локальном (sqllite) приложении это работает нормально:

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

Но на герою, используя 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 РАБОТАЕТ: консоль 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 >]

Как выполнить прямой SQL с Postgres ... SUM (имя столбца) и COUNT (*) должны работать, верно?

Ответы [ 2 ]

6 голосов
/ 05 февраля 2012

Здесь есть пара вещей.

Во-первых, find_by_sql вернет инициализированные объекты на основе возвращаемых данных, поэтому вы не видите ничего, возвращающегося из ваших подсчетов.

Чтобы сделать это с AR, вы можете сделать:

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

Это вернет число.То же самое с суммами:

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
1 голос
/ 14 марта 2013

Существует метод 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...