【发布时间】:2011-06-15 06:57:30
【问题描述】:
在 rails 3(如果您想在查询中使用 meta_where gem,也可以使用它),我遇到了一个非常棘手的查询,我一直在努力寻找:
假设我有两个模型,客户和购买,客户有很多购买。让我们将至少有 2 次购买的客户定义为“repeat_customer”。我需要查找过去 3 个月内每天的重复客户总数,例如:
Date TotalRepeatCustomerCount
1/1/11 10 (10 repeat customers by the end of 1/1/11)
1/2/11 15 (5 more customer gained "repeat" status on this date)
1/3/11 16 (1 more customer gained "repeat" status on this date)
...
3/30/11 150
3/31/11 160
基本上,我需要根据他们第二次购买的创建日期对客户计数进行分组,因为那是他们“获得重复状态”的时间。
这当然可以在 ruby 中实现,例如:
Customer.includes(:purchases).all.select{|x| x.purchases.count >= 2 }.group_by{|x| x.purchases.second.created_at.to_date }.map{|date, customers| [date, customers.count]}
但是,上面的代码会在Customer.all 和Purchase.all 的同一行上触发查询,然后在ruby 中进行一堆计算。我更喜欢在 mysql 中进行选择、分组和计算,因为它不仅速度更快,而且还减少了数据库的带宽。在大型数据库中,上面的代码基本上是没用的。
我一直在尝试在 rails/active_record 中创建查询,但即使使用了不错的 meta_where gem 也没有运气。如果必须,我也会接受纯 mysql 查询的解决方案。
已编辑:我会将其缓存(或向客户添加“重复”字段),但仅针对此简化问题。回头客的标准可以由客户随时更改(2 次购买、3 次购买、4 次购买等),所以很遗憾我必须当场计算。
【问题讨论】:
-
您能否制作一个表格来缓存此信息并在购买时生成它。这样就没有计算开销,您只需为用户计算一次状态。
-
这不是直接回答,但要扩展 Devin 的评论,您可以向客户添加一个名为 repeat_status_date 的列,并在购买对象上使用 after_save 回调编写它。
-
我会缓存它(或向客户添加一个“重复”字段),尽管只是为了这个简化的问题。回头客的标准可以由客户随时更改(2 次购买、3 次购买、4 次购买等),所以很遗憾我必须当场计算。
标签: mysql ruby-on-rails ruby-on-rails-3