Rails 4 可以使用 ActiveRecord 进行嵌套查询吗?

Can Rails 4 do nested queries with ActiveRecord?

我在我的 Rails 4 应用程序中编写了一个新的 SQL 查询用于一些统计分析。出于可维护性、可读性和一致性的目的,我更喜欢在 ActiveRecord 查询中而不是 SQL 中表达它,但我不知道该怎么做。

我发现一些代码使用嵌套 JOINs,但 none 用于嵌套 SELECTs

我有一个名为 groups 的 table,它与 group_members 具有一对多关系(这些也是 ActiveRecord 对象组和组成员)。

我正在尝试计算所有成员计数中成员数量为 X 的群组的数量。这是一个显示有多少成员组的分布图。

这是我编写的查询,目前 运行 使用 ActiveRecord::Base.connection.exec_query:

SELECT members_count, COUNT(members_count) 
FROM (
      SELECT COUNT(*) AS members_count, "group_id" AS group_id 
      FROM "groups" 
      INNER JOIN "group_members" ON "group_members"."group_id" = "groups"."id" 
      GROUP BY "group_id"
     ) AS groups_count 
GROUP BY members_count 
ORDER BY members_count;

如何将其转换为 ActiveRecord 查询? 我遇到的问题是嵌套的 SELECT 调用。在 Rails 4 中的 ActiveRecord 中可以实现吗?

我强烈建议远离 ORM,转向类似 SQL 视图的东西。

有一个很棒的 gem 可以与 ruby 中的 SQL 视图交互,称为 Scenic:https://github.com/scenic-views/scenic

性能是一个明显的原因,但我也认为您会发现在 SQL 中实际上更容易推理这类问题。 ActiveRecord 应该是一个工具,可以帮助您不必编写真正愚蠢的小查询,而不是从您的应用程序中完全消除原始 SQL。

也就是说,select 可以像 ActiveRecord 中的 join 一样处理嵌套查询。

恕我直言,把宝石留到真正需要它们的时候使用。

您可以将子查询与 fromselect:

组合
Group
  .from(
    Group
      .joins(:group_members)
      .select('COUNT(*) AS members_count, group_members.group_id')
      .group('group_members.group_id')
  )
  .select("members_count", 'COUNT(members_count)')
  .group("members_count")
  .order("members_count")

# SELECT "members_count", COUNT(members_count)
# FROM (
#   SELECT COUNT(*) AS members_count, group_members.group_id
#   FROM "groups"
#   INNER JOIN "group_members" ON "group_members"."group_id" = "groups"."id"
#   GROUP BY group_members.group_id
# ) subquery
# GROUP BY "members_count"
# ORDER BY "members_count" ASC