在Rails 3(也有,如果你觉得在你的查询中使用它meta_where宝石),我得到了我一直在敲打我的头一个真正棘手的查询:整蛊Rails3中/ MySQL查询
假设我有两个模型,顾客和购买,顾客有很多购买。让我们将至少有两件购物的顾客定义为“repeat_customer”。我需要每天找repeat_customers总数在过去的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
相同的路线查询,然后做了一堆计算的红宝石。我更喜欢在mysql中进行选择,分组和计算,因为它不仅速度更快,而且还减少了数据库中的带宽。在大型数据库中,上面的代码基本上是无用的。
我一直在尝试一段时间来召唤rails/active_record中的查询,但即使使用meta_where gem也没有运气。如果必须的话,我也会接受纯粹的mysql查询解决方案。
编辑:我会缓存它(或添加一个“重复”字段给客户),虽然只是为了这个简化的问题。客户在任何时候都可以改变重复客户的标准(2次购买,3次购买,4次购买等),所以不幸的是我不得不在现场进行计算。
您是否可以创建一张缓存此信息并在购买时生成该信息的表格。这样就没有计算开销,你只需要为用户计算一次状态。 – 2011-06-14 01:19:53
这并不直接回答,但为了扩展Devin的评论,您可以向客户添加一个名为repeat_status_date的列,并在购买对象上使用after_save回调进行编写。 – 2011-06-14 01:44:53
我会缓存它(或为客户添加一个“重复”字段),但仅限于此简化问题。客户在任何时候都可以改变重复客户的标准(2次购买,3次购买,4次购买等),所以不幸的是我不得不在现场进行计算。 – Charles 2011-06-14 17:19:59