我想让每次返回的数据都是随机的且要满足下面的一个条件.不要写死一个一个值去判断,不去count()具体的值
条件 : 随机查询的数据满足每个专业的最少有一个人
我的想法是
达到后,结束
通过下面的代码,能够查询出每个专业的人数,可以用来做判断,是否满足条件,但是这是查询全部的.
当我想要查询只要10个人时,下面的代码查的是所有人.
但是,我要是先随机查询出10个人,那么这10个人不一定会满足条件.如果一直随机查询直到满足条件,那就太浪费资源了
SELECT COUNT(t.zhuanye) c
FROM t_expert AS t
GROUP BY t.zhuanye
HAVING c>=2
现在,我疑惑的地方是这个存贮函数如何写,怎么样才能在查到相应的数据后,停止查询.
我对MySQL只是简单了解.这个问题,困惑我很久了.
遇到复杂逻辑的需求.不要寄托于数据库.而且数据对于一些不太复杂的逻辑来讲速度很快.
但是,一旦涉及我这种看起来还可以,但实际上要求很是复杂.
不如先把所有数据查出来,再去按照需求去自己取值.
但是这就有涉及到**另一个问题**
所以,我想,按分层查询,假设男女最少各为3人.
那么,为了避免1000个男的,就只有6个女的这种情况(只为举例说明)
所以,我先查询男的取3个,再查询女的取3个.
但是这种情况,只能时候,字段值比较少的时候,多了还是麻烦.我现在还没有想好.等有空闲了,我再好好琢磨一下
2018-12-19
我想到,可以使用使用 IN() OR IN() 来减少数据量,查询时可以使用MySQL上的 FIND_SET_IN() 函数来简化
SELECT * FROM test WHERE id >= (SELECT floor(RAND() * (SELECT MAX(id) FROM test)));
上边的这个代码,是根据后边的随机数,查询随机的数据库记录条数。但是要强调的是,是连续的,就是从随机数开始一直显示到最后一条记录。
SELECT * FROM test WHERE id >= (SELECT floor(RAND() * (SELECT MAX(id) FROM test))) ORDER BY id LIMIT 0,5;
第二条,sql 语句 。就会限制数据库的查询条数。像我写的就是选取了5条。
但是,还会有一些问题,比如,我的数据库总共有10条信息记录,限制是查询 5 条,随机数是7的话,只会有第7、8、9、10,这三条记录。
如果随机数是5,则会显示5、6、7、8、9 这5条记录。
只做一个思路的参考,不肯定能解决你的问题,我啥问题,一起探讨。
随机查询,方法可以有很多种。比如,查询出所有记录,然后随机从列表中取n条记录。使用程序便可实现。可是程序实现必须查询出所有符合条件的记录(至少是所有符合条件的记录id),然后再随机取出n个id,查询数据库。但是效率毕竟没有数据库中直接查询得快。下面介绍mysql中怎样随机查询n条记录。
1.最简单的办法order by rand(),示例
select * from question q where q.level
=1 order by rand() limit 1;
此写法,可以将查询出的结果集打乱,limit n条记录后,得到n条随机的记录,这n条记录也是随机顺序的,就是效率有点慢,但是很随机。
2.如果记录id保持连续增长,中间不间断,则可以用其它方式替代上述语句,示例
复制代码
#随机查询(记录大于某个数,效率高)
select q1.* from question q1 inner join (select (min(q2.id) + round(rand()*(max(q2.id) - min(q2.id)))) as id from question q2 where q2.level
=1) as t
on q1.id >= t.id limit 1;
#效率略低
select q.* from question q where q.id > (select t.id from (
select (min(q2.id) + round(rand()*(max(q2.id) - min(q2.id)))) as id from question q2 where q2.level
=1
) t) limit 1;
#效率极低,比order by rand还低(可能针对每条记录都作了子查询,结果不不连续,很随机)
select q.* from question q where q.id > (select (min(q2.id) + round(rand()*(max(q2.id) - min(q2.id)))) from question q2 where q2.level
=1) limit 1;
复制代码
法2的实现原理是,找出符合条件的记录的id范围[minId,maxId],然后随机生成一个id,使id在范围内,算法为id=minId+[0,maxId-minId], [0,maxId-minId]可使用round四舍五入函数和rand随机函数实现。然后大于等于此id的记录既是符合条件的随机的记录。上述写法仅针对查询出一条记录。如果查询出n条记录则sql语句改为:
select q1.* from question q1 inner join (select (min(q2.id) + round(rand()*(max(q2.id)-2 - min(q2.id)))) as id from question q2 where q2.level
=1) as t
on q1.id >= t.id limit 3;
如上,随机取连续的3条记录,max的值减掉二,就是使范围缩小2,保证随机出来的id,大于等于它时仍可查出3条记录。
如果 maxId-(n-1)-minId为负数,就是说数据记录范围内没有n条记录,则上述语句报错,改进版如下:
select q1.* from question q1 inner join (
select (min(q2.id) + round(rand()* ( case when (max(q2.id)-2)>min(q2.id) then max(q2.id)-2 - min(q2.id) else 0 end ))) as id,min(q2.id) as minId,max(q2.id) as maxId from question q2 where q2.level
=2
) as t
on q1.id >= t.id and q1.id between t.minId and t.maxId limit 3;
附上随机函数的测试代码:
select 10*RAND(); #[0,10)
select FLOOR(10*RAND());#[0,9]
select CEILING(10*RAND()); #[1,10]
select ROUND(10*RAND()); #[0,10]
建议不要把简单问题复杂化,往往2个简单的需求组合到一起就变成一个复杂的问题了。
我觉得可以考虑先随机全部数据,然后按照条件要求,在后台或存储过程实现。而不是硬要用SQL实现。