Sql 如何有效地(以独立于数据库的方式)从表中选择随机记录?
这似乎是一个非常简单的问题,但它并没有像我预期的那么简单 我有一个俱乐部有俱乐部成员,我想从一个俱乐部中随机抽出两名成员 使用RANDOM() 一种方法是使用随机排序:Sql 如何有效地(以独立于数据库的方式)从表中选择随机记录?,sql,ruby-on-rails,activerecord,Sql,Ruby On Rails,Activerecord,这似乎是一个非常简单的问题,但它并没有像我预期的那么简单 我有一个俱乐部有俱乐部成员,我想从一个俱乐部中随机抽出两名成员 使用RANDOM() 一种方法是使用随机排序: club.members.find(:all, :order => 'RANDOM()').limit(2) 但是,对于SqLite(开发数据库)和Postgres(生产数据库),这是不同的,因为在MySql中,命令是RAND() 虽然我可以开始写一些关于这一点的包装,但我觉得事实上,它还没有完成,而且似乎不是Activ
club.members.find(:all, :order => 'RANDOM()').limit(2)
但是,对于SqLite(开发数据库)和Postgres(生产数据库),这是不同的,因为在MySql中,命令是RAND()
虽然我可以开始写一些关于这一点的包装,但我觉得事实上,它还没有完成,而且似乎不是ActiveRecord的一部分,这告诉我一些事情,随机可能不是正确的方式
直接使用项目的索引将项目取出
另一种方法是按顺序提取集合,然后从中选择随机记录:
首先,我们需要生成与成员对应的两个唯一索引序列:
all_indices = 1..club.members.count
two_rand_indices = all_indices.to_a.shuffle.slice(0,2)
这将生成一个具有两个保证唯一和随机的索引的数组。我们可以使用这些索引来提取我们的记录
@user1, @user2 = Club.members.values_at(*two_rand_indices)
最好的方法是什么?
虽然第二种方法看起来很不错,但我也觉得我可能遗漏了一些东西,可能把一个简单的问题复杂化了。很明显,我不是第一个解决这个问题的人,那么通过它的最佳、最高效的SQL方法是什么?MySQL中的Order By RAND()函数:
ORDER BY RAND() LIMIT 4
当上面是查询中的最后一个子句时,这将随机选择4行。尝试使用gem,它实现了您提到的第二种方法。第一种方法的问题是,它通过不可索引的表达式对整个表进行排序,只取两行。这不能很好地扩展 第二种方法的问题类似,如果表中有109行,那么将从
到\u a
生成一个大数组。这将需要大量的内存和时间来洗牌它
另外,通过在处使用values\u,您不认为从1到count的每个主键值都有一行,没有间隔吗?你不应该这样想
我的建议是:
计算表中的行数
c = Club.members.count
在1和计数之间
r_a = 2.times.map{ 1+Random.rand(c) }
使用查询您的表。
不要使用orderby
,只需依赖RDBMS的任意排序即可
for r in r_a
row = Club.members.limit(1).offset(r)
end
另见:
没有真正有效的独立于数据库的方法。为什么您需要它独立于数据库?这实际上取决于数据库以及您希望结果的随机性。@mitchwheat我正在SqLite上开发并部署在PosGres上,因此需要它同时跨数据库和随机性。我还希望尽可能多地编写与DB无关的代码作为良好的实践。约翰-我只是在寻找合理的随机性,不一定是真正的随机性。Craig-tyIt会的,但要以全表扫描为代价。