【问题标题】:ActiveRecord limit users returned from a collection of company_idsActiveRecord 限制从 company_ids 集合返回的用户
【发布时间】:2019-12-06 19:51:54
【问题描述】:

我有一个 company_id 数组
User模型中,我想find_by company_ids,但是对于每个company_id,返回的用户列表不能超过5个用户。我该怎么做。

我试过这样做

User.where(company_id: [1, 2, 3]).group('users.company_id').having('count(company_id) <= 5')

但这只会返回公司用户不超过5人的集合。而且,这不会返回所有记录。

我想要做的是,对于company_ids = [1, 2, 3],该集合应该能够为 company_id 1、company_id 2、company_id 3 返回最多 5 个用户,而不是为所有这些 company_id 加载所有用户。

【问题讨论】:

  • 你用的是什么关系型数据库?
  • 我正在使用 MySql。
  • 什么版本@arjun?
  • @SebastianPalma MySql 版本是 5.7.28,Rails 版本是 5.2.4

标签: sql ruby-on-rails activerecord ruby-on-rails-5


【解决方案1】:

由于您的 MySQL 版本,我认为您可以进一步使用 UNION ALL

您可以创建一个查询,通过company_id 选择用户,然后应用LIMIT

(select * from users where company_id = 1 LIMIT 2)
UNION ALL
(select * from users where company_id = 2 LIMIT 2)
UNION ALL
(select * from users where company_id = 3 LIMIT 2)

由于 Rails 没有对 UNION 查询的内置支持,您可以创建自己的语句:

sql = [1, 2, 3].map { |id| "(SELECT * FROM users WHERE company_id = #{id} LIMIT 2)" }
               .join(" UNION ALL ")
User.find_by_sql(sql)

使用 MySQL8+ 更新

SELECT id, name, company_id
FROM (
  SELECT id, name, company_id, ROW_NUMBER() OVER w AS company_user
  FROM users
  WINDOW w AS (PARTITION BY company_id)
) users
WHERE company_user <= 2;

ActiveRecord 方式是:

User
  .select(:id, :name, :company_id)
  .from(
    User.select(:id, :name, :company_id, 'ROW_NUMBER() OVER w AS company_user')
        .from('users WINDOW w AS (PARTITION BY company_id)')
  )
  .where('company_user <= 2')

【讨论】:

  • 谢谢,这有帮助。您提到的基于我的 MySql 版本 UNION ALL 可以完成这项工作。如果它是不同的版本,还有其他方法可以做到这一点吗?
  • 是的,在 MySQL 8 中,您可以使用 ROW_NUMBER()PARTITION BY。检查更新的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 2011-02-20
  • 1970-01-01
  • 2019-06-28
  • 1970-01-01
相关资源
最近更新 更多