0

Tags我的rails 应用程序中有一个列表,这些列表与Posts使用Taggings. 在某些观点中,我想展示 5 个最常用标签的列表,以及它们被标记的时间。要创建一个完整的示例,假设一个包含 3 个帖子的表:

POSTS
ID | title
1  | Lorem
2  | Ipsum
3  | Dolor

还有一张有 2 个标签的桌子

TAGS
ID | name
1  | Tag1
2  | Tag2

现在,如果帖子 1 用 Tag1 标记,而帖子 2 用标记 1 和 2 标记,我们的标记表如下所示:

TAGGINGS
tag_id | post_id
1      | 1
1      | 2
2      | 2

那么问题是如何获取所需的信息(最好不要多次返回数据库)以显示以下结果:

Commonly used tags:
tag1 (2 times)
tag2 (1 time)

我已经设法通过包含标签、tag_id按计数分组和排序来使用 MySQL 做到这一点:

红宝石:

taggings = Tagging.select("*, count(tag_id) AS count").includes(:tag).group(:tag_id).order('count(*) DESC').limit(5)
taggings.each { |t| puts "#{t.tag.name} (#{t.count})" }

但是,我正在将应用程序迁移到 Heroku,因此我需要迁移到 PostgreSQL 9.1。不幸的是,Postgres 的严格性破坏了该查询,因为它要求在子句中指定所有字段。group by我试过那样做,但结果是我不能再使用t.count来获取行数了。

所以,最后要回答这个问题:

从 postgres (v9.1) 查询此类信息并将其显示给用户的最佳方法是什么?

4

1 回答 1

2

你的问题:

不幸的是,Postgres 的严格性破坏了该查询,因为它要求在 group by 子句中指定所有字段。

现在,这在 PostgreSQL 9.1 中有所改变(引用 9.1的发行说明):

在子句中指定主键时允许查询目标列表中的非GROUP BYGROUP BY(Peter Eisentraut)

更重要的是,你描述的基本查询甚至不会遇到这个:

显示 5 个最常用标签的列表,以及它们被标记的时间。

SELECT tag_id, count(*) AS times
FROM   taggings
GROUP  BY tag_id
ORDER  BY times DESC
LIMIT  5;

在任何情况下都有效。

于 2012-08-07T14:15:34.387 回答