计算并订购每个推荐人

时间:2016-12-24 22:52:02

标签: sql ruby-on-rails ruby

我先说这是我对铁轨和开发的新手。

概述

我有一个简单的推荐系统,我想计算每个订阅者引用其他人的次数,然后根据转介次数按降序排列所有订阅者。

详情

这是我的Subscribers表:

| id | email | referred_by |

referred_by包含推介订阅者的subscriber_id

我想要的是循环遍历表中每个订阅者的方法/查询:

  1. 计算其ID显示在referred_by列中的次数。
  2. 根据订阅者总数对订阅者进行排序。
  3. 我正在考虑下面的问题,但我的一部分问题是,我不知道在代码库之外测试方法和查询的地点和方式,所以我不知道怎么做测试一下。我假设在控制台中,但我不了解如何在那里进行多部分方法或查询。

    Subscriber.all.each do |referrer|
      Subscriber.all.each do |subscriber|
        if referrer.id == subscriber.referred_by
          referrals += 1
        else
          next
        end
      end
    end
    # Then order descending
    

4 个答案:

答案 0 :(得分:1)

Select A.id
      ,A.email
      ,case when B.referrals is null then 0 else  B.referrals end as referrals
 From YourTable A
 Left Join ( 
        Select referred_by,count(*) as referrals
         From  YourTable 
         Where referred_by is not null
         Group By referred_by
      ) B 
    On A.id = B.referred_by
 Order By B.referrals Desc,A.email

会返回类似这样的内容

id  email               referrals 
4   email_4@mail.com    3
1   email_1@mail.com    2
2   email_2@mail.com    0
3   email_3@mail.com    0
  

修改

如果要排除非推荐(零计数),请将左连接更改为内连接

答案 1 :(得分:1)

另一种方法是使用rails:counter_cache选项进行belongs_to关联。在表格中添加一个名为" referrals_count" (或者你更喜欢的东西),它将记录他们所引用的所有订户。我认为你还需要改变你的" refer_by"列到" refer_by_id"所以你可以正确设置关联。您的订阅者模型如下所示:

class Subscriber < ApplicationRecord
  belongs_to :referred_by, class_name: "Subscriber", counter_cache: :referrals_count
end

然后你的查询将是:

@subscribers = Subscriber.order(referrals_count: :desc)

您可以在此处获取有关Rails counter_cache的更多信息:http://guides.rubyonrails.org/association_basics.html

我更喜欢这样做,所以我不必编写冗长而复杂的SQL查询。

答案 2 :(得分:0)

这是一个最好留给您的数据库的任务,它对这些任务进行了各种优化。

limit

使用较小的数据集,这就足够了,但您可能希望链接到having,甚至可以在推荐数量上设置一个底线(即,仅显示至少有1个推介的用户)与{{1}}。

通常我也会在这里转换字符串以更好地利用Arel,但它使解决方案变得更加困难,因此我没有这样做。另外一次做作业!

注意:我在这里使用略有不同的术语/列,以使此示例更易于理解和遵循。确保你不要盲目地复制粘贴。 :)

答案 3 :(得分:0)

我建议将其作为一个sqlstatement来让数据库为你工作而不是循环。 SQLServers在这类事情上更擅长

GridView

这将作为存储过程在数据库本身中,然后我从应用程序中调用它。它不是rubyesq,但它将工作放在它所属的位置。