Добавление столбцов таблицы в группу по выражению - Ruby on Rails - Postgresql - PullRequest
5 голосов
/ 23 апреля 2010

Я пытаюсь использовать Heroku, и, очевидно, Postgresql намного более строг, чем SQL, для агрегатных функций.Когда я нажимаю на Heroku, я получаю сообщение об ошибке ниже.

По другому вопросу Я спросил, что получил несколько указаний, в которых говорилось, что я должен просто добавить столбцы в мою группу по пунктам, и я не уверен, как это сделать.Смотрите полную ошибку ниже и индекс PostsControll #.

SELECT posts.*, count(*) as vote_total FROM "posts"   INNER JOIN "votes" ON votes.post_id = posts.id   GROUP BY votes.post_id ORDER BY created_at DESC LIMIT 5 OFFSET 0):

PostsController

def index
    @tag_counts = Tag.count(:group => :tag_name, 
       :order => 'count_all DESC', :limit => 20)
       conditions, joins = {}, :votes

    @ugtag_counts = Ugtag.count(:group => :ugctag_name, 
       :order => 'count_all DESC', :limit => 20)
       conditions, joins = {}, :votes

    @vote_counts = Vote.count(:group => :post_title, 
          :order => 'count_all DESC', :limit => 20)
          conditions, joins = {}, :votes


       unless(params[:tag_name] || "").empty?
         conditions = ["tags.tag_name = ? ", params[:tag_name]]
         joins = [:tags, :votes]
       end
       @posts=Post.paginate(
                 :select => "posts.*, count(*) as vote_total", 
                 :joins => joins, 
                 :conditions=> conditions, 
                 :group => "votes.post_id", 
                 :order => "created_at DESC",
                 :page => params[:page], :per_page => 5)
        @popular_posts=Post.paginate(
                 :select => "posts.*, count(*) as vote_total", 
                 :joins => joins, 
                 :conditions=> conditions, 
                 :group => "votes.post_id", 
                 :order => "vote_total DESC",
                 :page => params[:page], :per_page => 3)

    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @posts }
      format.json { render :json => @posts }
      format.atom
    end
  end

Ответы [ 4 ]

3 голосов
/ 23 апреля 2010

MySQL и SQLite настолько гибки, что позволяют использовать столбцы в списке выбора без указания имени в предложении GROUP BY (а не внутри агрегатной функции, такой как COUNT()). Но такой уровень гибкости может привести к неоднозначным запросам.

PostgreSQL строг в соответствии со стандартом ANSI SQL. Все остальные протестированные мной базы данных (Oracle, Microsoft, IBM DB2, Firebird) в этом вопросе ведут себя как PostgreSQL.

Вам нужно сделать так, чтобы список из posts столбцов в вашем списке выбора соответствовал столбцам, указанным в предложении GROUP BY. Сделайте это, выбрав меньшее количество столбцов, или добавив столбцы в :group.

Я не эксперт по Rails, и я не могу найти пример того, как передать несколько столбцов в качестве аргумента :group. Глядя на код active_record / base.rb, выясняется, что он просто копирует значение параметра в буквальное предложение SQL GROUP BY. Поэтому я бы предположил (не попробовав), что вы можете сделать это:

...
:group => "posts.post_id, posts.foo, posts.bar, posts.baz", 
...

Обратите внимание, что вы должны назвать каждый столбец , который есть в вашем списке выбора, который не является частью агрегатной функции.

1 голос
/ 22 января 2011

Я придумал вариант, который заключается в создании динамических, а не во время компиляции изгибов имени таблицы.

model_columns = Model.column_names.collect do | c |"# {Model.table_name}. # {C}" end.join (",")

1 голос
/ 23 апреля 2010

Вы пробовали просто перейти на использование posts.id, например:

SELECT posts.*, count(*) as vote_total FROM "posts"   INNER JOIN "votes" ON votes.post_id = posts.id   GROUP BY posts.id ORDER BY created_at DESC LIMIT 5 OFFSET 0);

Если это так, чем набор результатов отличается от того, что вы получаете с существующим SQL?

0 голосов
/ 03 января 2011

Я только что имел дело с этой проблемой на Rails 3. Вот решение, которое я нашел:

group_models = [Post, Vote, etc.]
group_columns = ['"votes"."post_id"'] # whatever column you were specifying with :group 
group_models.each do |model|
  group_columns += model.column_names.map { |col| "\"#{model.table_name}\".\"#{col.name}\"" }
end
Post.where(whatever...).group(group_columns)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...