Sql 计算并排序每个推荐人的推荐数量
首先,我要说我是rails和开发的新手 概述 我有一个简单的转介系统,我想计算每个订阅者转介他人的次数,然后根据转介次数将所有订阅者按降序排列 详细信息 这是我的Sql 计算并排序每个推荐人的推荐数量,sql,ruby-on-rails,ruby,Sql,Ruby On Rails,Ruby,首先,我要说我是rails和开发的新手 概述 我有一个简单的转介系统,我想计算每个订阅者转介他人的次数,然后根据转介次数将所有订阅者按降序排列 详细信息 这是我的订阅者表: | id | email | referred_by | referenced\u by包含转介订户的订户id 我想要的是一个方法/查询,它循环遍历表中的每个订阅者,并且: 统计其id出现在所引用的列中的次数 按用户拥有的转介总数订购订户 我是按照下面的思路思考的,但我的部分问题是,我不知道在哪里以及如何在代码库之外测试方
订阅者表:
| id | email | referred_by |
referenced\u by
包含转介订户的订户id
我想要的是一个方法/查询,它循环遍历表中的每个订阅者,并且:
统计其id出现在
所引用的列中的次数
按用户拥有的转介总数订购订户
我是按照下面的思路思考的,但我的部分问题是,我不知道在哪里以及如何在代码库之外测试方法和查询,所以我不知道如何测试。我假设是在控制台中,但我不知道如何在那里执行多部分方法或查询
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
这是一项最好留给您的数据库完成的任务,它针对这些任务进行了各种优化
# Fetch subs who have referred others, ordered by number of referrals
referrers = Subscriber.group('referrer_id').order('count(referrer_id) desc')
# Select number of referrals alongside referrer data
referrers = referrers.select('count(referrer_id) as referral_count').select('*')
# Example of using the data:
referrers.each do |referrer|
puts "#{referrer.name} referred #{referrer.referral_count} others"
end
对于一个小的数据集,这就足够了,但您可能希望在限制
,甚至在有
的情况下设置一个最低的推荐数量(即,仅显示至少有一个推荐的用户)
通常我也会在这里转换字符串,以便更好地使用Arel,但这会使解决方案复杂化,使其更难摸索,所以我没有这样做。下次再做作业
注意:我在这里使用了稍微不同的术语/列,使这个示例更容易理解和遵循。确保不要盲目复制粘贴。:) 我建议将此作为一个sqlstatement,让数据库为您完成工作,而不是循环。SQLServer在这方面要熟练得多
select referred_by,
(select email
from subscribers sub
where id = subscribers.referred_by) as email,
count(referred_by) as referred
from subscribers
group by referred_by
order by count(referred_by) desc
这将作为存储过程存在于数据库中,然后我将从应用程序调用它。它不是rubyesq,但它把工作放在了它该做的地方
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
编辑
如果要排除非引用(零计数),请将Left Join更改为internal Join另一种方法是对“所属对象”关联使用rails:counter\u cache选项。在您的表中添加一个名为“referrals\u count”(或您更喜欢的内容)的列,该列将记录他们引用的所有订阅者的计数。我认为您还需要将“refered_by”列更改为“refered_by_id”,以便正确设置关联。您的订户型号如下所示:
class Subscriber < ApplicationRecord
belongs_to :referred_by, class_name: "Subscriber", counter_cache: :referrals_count
end
您可以在此处获得有关Rails计数器缓存的更多信息:
我更喜欢这样做,这样我就不必编写冗长复杂的sql查询。谢谢。我通读了文档,但我不完全确定我是否理解这是如何工作的。两个问题:1)我是否需要在我的订户控制器中执行其他操作来说明或保存推荐\u count
?该帖子未按原样处理。2) 为什么“refered_by”需要“refered_by_id”?1)通过将计数器\u缓存::refererals_count
添加到refered_id
的归属关联中,refered_count
自动更新。因此,在向订阅者添加references\u count
的迁移过程中,请确保为其指定一种整数类型和默认值0:add\u列:订阅者,:references\u count,:integer,默认值:0
。2)您需要将referenced\u by
更改为referenced\u by\u id
,以便正确设置归属关联。Rails希望任何关联列的末尾都有“\u id”,因为它希望列中的数据是该对象的id。在这种情况下,是订阅者的id引用了他们。检查一下我发送的链接的“属于”部分,它也在这一部分。ActiveRecord关联是RubyonRails的关键基础之一,因此我绝对建议您阅读我包含的链接,因为它将为您节省大量的代码编写时间。
@subscribers = Subscriber.order(referrals_count: :desc)