简体   繁体   English

Laravel根据另一个字段从表中选择随机行

[英]Laravel select random rows from table based on another field

There is a words table with 20000 records: 有一个包含20000条记录的words表:

ID      name      rank
1       word1     3 
2       word2     5019 
3       word3     12334 
4       word4     23
5       word5     544

I want to select 400 words randomly from this table but with this condition : 我要从此表中随机选择400个单词,但要满足以下条件:

first 20 words: select 20 words randomly from words with rank between 1 and 1000 第一20个字:选择随机地从20个字words 1和1000之间具有秩

second 20 words: select 20 words randomly from words with rank between 1000 and 2000 第二20个字:选择随机地从20个字words 1000和2000之间具有秩

And so on... 等等...

Do I have to do this in 20 separate queries? 我必须在20个单独的查询中执行此操作吗? How? 怎么样? Is there a better way? 有没有更好的办法?

I am using laravel 5.4 and Mysql, Also a raw query suggestion would be appreciated. 我正在使用laravel 5.4和Mysql,也欢迎使用原始查询建议。 Thank you 谢谢

Easy way 简单的方法

use a where clause to filter their rank, then use inRandomOrder() and take(20) to get 20 random ones. 使用where子句过滤其排名,然后使用inRandomOrder()和take(20)获得20个随机的。

Word::inRandomOrder()->where('rank', '>=', 1)->where('rank', '<=', 1000)->take(20);

Hard way 艰辛的道路

To get them all in one query, you might try some funky logic like this: 为了使它们全部集中在一个查询中,您可以尝试一些时髦的逻辑,如下所示:

first: define a view that returns the same table, but instead of rank, has categories, so category 1 for 1<=rank<1000, .... just to make the next step easier 首先:定义一个返回相同表的视图,但没有排名,而是具有类别,因此1 <= rank <1000,....的类别1只是为了使下一步更容易

now we can use partition by (see Trying to understand over() and partition by ). 现在我们可以使用partition by(请参阅尝试了解over()和partition by )。 Remember to order by RAND() inside the partition. 请记住按分区内的RAND()进行排序。 Order the result of all this by rownumber. 按行号对所有结果进行排序。

Now we have a result that looks like this: 现在,我们得到的结果如下所示:

rownumber      name      category
1              word1     1 
1              word2     2 
1              word3     3 
1              word4     4 
...
2              word21    1 
2              word22    2 
2              word23    3 
2              word24    4 
...
20             word381   1 
20             word382   2 
20             word383   3 
20             word384   4 
...

By taking 400 of these tuples, we will have 20 random samples of each of the 20 categories. 通过选取这些元组中的400个,我们将在20个类别的每一个中拥有20个随机样本。

Note-- ordering by RAND() can be slow, as explained here http://www.titov.net/2005/09/21/do-not-use-order-by-rand-or-how-to-get-random-rows-from-table/ 注意-通过RAND()进行订购可能会很慢,如此处所述:http: //www.titov.net/2005/09/21/do-not-use-order-by-rand-or-how-to-get -random-行-从表/

Edit : turn out partition by is for sql server only. 编辑 :结果分区仅用于sql server。 But you could do something similar in mysql 但是你可以在mysql中做类似的事情

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM