【问题标题】:How to obtain active genres in activerecord?如何在activerecord中获取活跃流派?
【发布时间】:2011-01-03 18:04:16
【问题描述】:

我正在使用 Rails 3 和 postgresql。我有以下流派:摇滚、氛围、另类、浩室。

我还注册了两个用户。一个以 rock 和另一个 house 作为他们的流派。我需要返回摇滚和房屋类型的对象。

我找到了两种方法来做到这一点。一个是使用组:

Genre.group('genres.id, genres.name, genres.cached_slug, genres.created_at, genres.updated_at').joins(:user).all

另一个使用 DISTINCT:

Genre.select('DISTINCT(genres.name), genres.cached_slug').joins(:user)

两者都返回相同的期望结果。但是哪一个性能更好呢?使用 group() 看起来很乱,因为我必须指出 Genre 表中的所有字段,否则我会收到这样的错误:

ActiveRecord::StatementInvalid: PGError: ERROR:  column "genres.id" must appear in the GROUP BY clause or be used in an aggregate function
: SELECT genres.id FROM "genres" INNER JOIN "users" ON "users"."genre_id" = "genres"."id" GROUP BY genres.name

【问题讨论】:

    标签: ruby-on-rails postgresql activerecord


    【解决方案1】:

    DISTINCTGROUP BY 通常会生成相同的查询计划,因此两种查询结构的性能应该相同。

    由于您没有使用任何聚合函数,因此您应该使用对您的情况最有意义的函数,我认为是这个函数:

    Genre.select('DISTINCT(genres.name), genres.cached_slug').joins(:user)
    

    稍后尝试阅读您的代码并记住您在此处所做的操作时会更加清楚,并且正如您所指出的那样,不会那么混乱。

    更新

    这取决于您使用的 Postgresql 版本。使用 GROUP BY 更快。对于 8.4 及更高版本,它们是相同的。

    【讨论】:

    • 使用以下内容进行了更多清理:Genre.select('DISTINCT(genres.name), Genres.*').joins(:user)
    猜你喜欢
    • 2023-04-01
    • 2012-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-04
    • 2018-05-03
    相关资源
    最近更新 更多