2

我有以下标签方法,它根据标签的使用次数选择标签,然后按该顺序排列它们。代码基于 railscasts 剧集:http ://railscasts.com/episodes/382-tagging 。

我将我的数据库从以前工作的 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:

标签.rb

class Tag < ActiveRecord::Base

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

标记.rb

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

如果有人需要更多代码,请大声喊叫。

4

2 回答 2

1

将“tags.id”作为错误消息添加到 group 子句就像一个魅力。

Tag.joins(:taggings).select('tags.*, count(tag_id) as "tag_count"').group("tags.id").order('tag_count desc')
于 2013-08-22T01:28:53.493 回答
1

您的错误消息为您提供由 rails 组成的 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)。我认为如果您尝试了解为什么会出现此错误并以正确的 ANSI 语法重写 SQL,这对您会更好,例如:

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
于 2013-08-22T04:51:37.353 回答