2013-08-22 44 views
2

我有以下标签方法,它会根据使用次数选择标签,然后按照该顺序排列它们。代码基于railscasts情节:http://railscasts.com/episodes/382-tagging转换rails mysql与postresql一起工作

我将我的数据库从mysql(以前的工作位置)更改为postgres,您可以在其中查看堆栈跟踪中生成的错误消息。

我该如何重构这个sql来使用postgresql?

def tags 
    Tag.joins(:taggings).select('tags.*, count(tag_id) as "tag_count"').group(:tag_id).order('tag_count desc') 
end 

堆栈跟踪

ActiveRecord::StatementInvalid - PG::GroupingError: ERROR: column "tags.id" must appear in the GROUP BY clause or be used in an aggregate function 
LINE 1: SELECT tags.*, count(tag_id) as "tag_count" FROM "tags" INNE... 
      ^
: SELECT tags.*, count(tag_id) as "tag_count" FROM "tags" INNER JOIN "taggings" ON "taggings"."tag_id" = "tags"."id" GROUP BY tag_id ORDER BY tag_count desc: 

tag.rb

class Tag < ActiveRecord::Base 

    has_many :taggings 
    has_many :questions, through: :taggings 
    #omitted for brevity 

tagging.rb

class Tagging < ActiveRecord::Base 
    belongs_to :tag 
    belongs_to :question 
end 

如果有人需要更多的代码就骂。

+1

的“A位必须出现在GROUP BY子句或者是在一个集合函数中使用“在这里搜索应该会得到你需要的答案。 –

+0

你说得对,回答是在问题中。 – dodgerogers747

回答

1

添加“tags.id”作为错误消息说,群组子句的工作就像一个魅力。

Tag.joins(:taggings).select('tags.*, count(tag_id) as "tag_count"').group("tags.id").order('tag_count desc') 
1

你的错误信息给你的SQL通过轨道

SELECT tags.*, count(tag_id) as "tag_count" 
FROM "tags" 
    INNER JOIN "taggings" ON "taggings"."tag_id" = "tags"."id" 
GROUP BY tag_id 
ORDER BY tag_count desc 

这是MySQL只语法,我必须说,我从来不喜欢的是MySQL允许的是,目前还不清楚如何列这是不是由在group by应该在结果集中显示。它应该是最小的?它应该是最大值?

我建议你只选择你需要的结果列,而不要使用select *。看起来你根本不需要tags.id(因为你已经有taggings.tag_id,并且因为inner join而平等)。我想这对你最好,如果你试着去理解为什么你收到此错误和重写你的SQL在适当的ANSI语法,例如:

select tags.name as tag_name, count(*) as "tag_count" 
from tags 
    inner join taggings on taggings.tag_id = tags.id 
group by tags.name 
order by tag_count desc