我正在运行以下查询,目的是返回一组唯一的customer
个对象:
Customer.joins(:projects).select('customers.*, projects.finish_date').where("projects.closed = false").uniq
但是,如果客户有多个项目处于活动状态(例如,closed = true),则此代码将生成重复项。如果我从projects.finish_date
子句中删除select
,则此查询将按预期工作。但是,我需要在那里能够对该列进行排序。
如何让此查询返回一组唯一的客户?
答案 0 :(得分:0)
如何让此查询返回一组唯一的客户?
这并不完全有意义,可能不是你想要的。
问题是您正在加入projects
表,此时同一客户可能有多行具有不同的项目finish_date
。这些行 唯一,将作为多个唯一Customer
个对象返回,每个对象的finish_date
不同。
如果您只想要其中之一,Rails如何确定哪一个?如果只有一个客户对象返回一个finish_date
,如果该客户真的有10个项目,每个项目都有不同的finish_date
,那么这不是问题吗?
相反,你可能想要这样的东西:
customers = Customer.joins(:projects).select('customers.*, projects.finish_date').where("projects.closed = false").uniq
customers.group_by(&:id)
将您的所有同一客户组合在一起。
或者,你可能想要:
projects = Project.where(closed: false).includes(:user)
users = projects.map(&:user).uniq
在任何一种情况下,您都是从所有用户项目联接的超集中生成一组唯一的用户。
RE您的意见:
如果您想获得包含最新关联项目的客户列表,可以在where
中使用子查询:
select customers.*, projects.finish_date from customers
inner join projects on projects.customer_id = customers.id
where projects.id = (
select id from projects
where customer.id = project.customer_id
and closed = false
order by finish_date desc
limit 1
)
您可以使用ActiveRecord通过在where
中嵌入子查询来表达这一点:
Customer.joins(:projects)
.select('customers.*, projects.finish_date as finish_date')
.where('select id from projects where customer.id = project.customer_id and closed = false order by finish_date desc limit 1')
我不知道这会对你有什么影响,但我怀疑是不好的。
在尝试使用SQL进行优化之前,我总是坚持使用简单的includes
和in-Ruby过滤器。