大家讨论一下:取的概率的算法放在SQL实现好呢,还是放在程序里处理更好

xiaoxiao1984 2006-06-21 05:38:01
如题
大家能都说说自己的看法么,并给出理由或者demo什么的
100分不够可以再加
谢谢大家

...全文
355 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiaoxiao1984 2006-06-30
  • 打赏
  • 举报
回复
顶啊顶,把帖子顶起来
xiaoxiao1984 2006-06-26
  • 打赏
  • 举报
回复
to waterfirer(水清):
select * from table sample(k) 也可以实现取k%的记录
尝试了一下,好象取得记录的条数不总是确定的
SQL> select count(1) from t1;

COUNT(1)
----------
100
SQL> select * from t1 sample(10);

MONTH MONEY
---------- ----------
19 19
22 22
25 25
35 35
70 70
78 78
84 84
87 87
91 91

已选择9行。

SQL> select * from t1 sample(10);

MONTH MONEY
---------- ----------
3 3
4 4
26 26
35 35
41 41
43 43
82 82
86 86

已选择8行。

SQL> select * from t1 sample(10);

MONTH MONEY
---------- ----------
3 3
4 4
26 26
35 35
41 41
43 43
82 82
86 86

已选择8行。

SQL> select * from t1 sample(10);

MONTH MONEY
---------- ----------
3 3
4 4
26 26
35 35
41 41
43 43
82 82
86 86

已选择8行。

SQL> select * from t1 sample(10);

MONTH MONEY
---------- ----------
3 3
9 9
13 13
30 30
33 33
35 35
44 44
51 51
65 65
74 74
90 90

MONTH MONEY
---------- ----------
93 93

已选择12行。

SQL> select * from t1 sample(10);

MONTH MONEY
---------- ----------
3 3
9 9
13 13
30 30
33 33
35 35
44 44
51 51
65 65
74 74
90 90

MONTH MONEY
---------- ----------
93 93

已选择12行。

SQL> select * from t1 sample(10);

MONTH MONEY
---------- ----------
10 10
17 17
20 20
56 56
73 73
94 94

已选择6行。
xiaoxiao1984 2006-06-26
  • 打赏
  • 举报
回复
可以这么理解么:
1. 数据库的话,只需要一次就可以取得所需要的数据集;
2. 通过程序实现
1)不是特别清楚 waterfirer(水清) 所说的需要先将数据全部取出,然后再随机取出需要的数据应该怎么做,再次麻烦 waterfirer(水清) 解释一下
2)我的理解是如果需要随机取得确定level的题N道,那么,需要建立一个数组,记录已经被取出的题的序号,根据N进行循环,每次循环随机生成一个随机数,然后检查数组中是否已经存在该随机数对应的题目序号,如果不存在,那么把随机数生成的题目序号放入数组;如果存在,继续循环,直至取得N个题目序号;最后按照数组去数据库一次性取得记录;(前提:按照随机数生成题目序号在数据库中一定存在)
想法不是特别完善
欢迎大家拍砖,多多指点
yqwd911 2006-06-26
  • 打赏
  • 举报
回复
上次有人讲dbms_random产生的是伪随机数。
但是我想只要是通过算法实现的随机数应该都差不多吧。

个人认为放在程序里比较好,比较灵活,适当减轻数据库负担。
bein9 2006-06-25
  • 打赏
  • 举报
回复
通过程序实现不需要全部取出数据吧。取出count,然后产生1-count的随机数 R ,选择第R条记录不就行了吗?取出全部数据,太不划算了。呵呵
waterfirer 2006-06-25
  • 打赏
  • 举报
回复
通过数据库实现和程序实现的比较
1、通过数据库实现
Oracle可以通过我在
http://community.csdn.net/Expert/topic/4832/4832629.xml?temp=.4810602
中给出的方法来实现
select ID,name,star_level from (select ID,name,star_level,round(dbms_random.value(1,15))-star_level t from tbl_A) where t<=0

select ID,name,star_level from (select ID,name,star_level,mod(abs(dbms_random.random),15)-star_level t from tbl_A) where t<=0

select ID,name,star_level from (select ID,name,star_level from tbl_A order by dbms_random.value*(1+star_level/k) desc) where rownum<5

select * from table sample(k) 也可以实现取k%的记录

用数据库做可以直接将需要的数据取出。不同的数据库需要用不同的函数处理

2、通过程序实现
需要先将数据全部取出,然后再随机取出需要的数据。算法不依赖于数据库



xiaoxiao1984 2006-06-23
  • 打赏
  • 举报
回复
to sozdream():
1. select to_char(current_timestamp(6),'YYYY-MM-DD hh24:mi:ssxff') from dual;
小数部分并不是随机数,而是一个确定的时间;所以产生的并不是一个水平分布的随机数;
2. 245732 / 1000000 * 150000 = 368598, 那么新得到的368598就是随机选中的题目.
由于产生的245732 并不是水平分布的随机数,那么通过它计算出选中题号的概率就不是 1/总题数,那么就无法保证后面的level 1选中率为 50%等
xiaoxiao1984 2006-06-23
  • 打赏
  • 举报
回复
呵呵,可以用dbms_random实现
想知道用数据库实现和用程序实现两者的优劣
jametong 2006-06-23
  • 打赏
  • 举报
回复
使用dbms_random不可以吗?
龙翔飞雪 2006-06-21
  • 打赏
  • 举报
回复
刚想到上面的提供的解决方案有个小小的漏洞,
那就是取秒的小数部分,可能取的两次是相同(这个...1000000分之一的概率)或则调整后值相同.
那就会产生两次选一样的题~

不过解决这个问题应该很easy吧~ 选中一题就往随便哪张表里塞条记录,说明这题已经被用啦,以后不能再用
龙翔飞雪 2006-06-21
  • 打赏
  • 举报
回复
1. 首先是随机到底怎么产生... 像JAVA,C#,SQL里的Random产生的数字是固定的(每次RUN都是这些数字)
解决这个问题,想来想去,至于取秒的小数部分,够随机!
select to_char(current_timestamp(6),'YYYY-MM-DD hh24:mi:ssxff') from dual;
查询结果:
2006-06-21 17:51:41.245732, 取后面的245732;
这6个数字够权威,够随机了吧~

2. 其次,怎么选择题目? (比如试题表是 EXAM)
先取总数~
select count(1) from EXAM;
得到结果:
150000 (假设题库有15万题)
将上面得到的 245732 / 1000000 * 150000 = 368598, 那么新得到的368598就是随机选中的题目.

3. 上面两步基本可以解决了随机选题的问题,但不能解决试题还有级别,不同级别之间,选中概率不同的问题:
解决方法如下:
例:level 1选中率为 50%
例:level 2选中率为 30%
例:level 3选中率为 10%
例:level 4选中率为 7%
例:level 5选中率为 3%
一共要选多少题是已知的,例如要选100题出来.
那么可以得到需要选出 50题(1级) 30题(2级) 10题(3级) 7题(4级) 3题(5级);

4.
select count(1) from EXAM where level=1;
select count(1) from EXAM where level=2;
select count(1) from EXAM where level=3;
select count(1) from EXAM where level=4;
select count(1) from EXAM where level=5;
得到所有级别的试题数的结果:(假设结果如下)
100000
30000
10000
5000
5000 ,
好了, 现在的问题就转变成,怎样在100000题1级试题中选出50题, 30000题2级试题中选出30题 .......

5. 将步骤4中的问题用步骤1,2来解, 完事~
(有不足之处~ 请指出! 这个过程需要代码和SQL结合来完成, 下一个SQL就能完成的人实在...高)
xiaoxiao1984 2006-06-21
  • 打赏
  • 举报
回复
这个帖子引起的疑问:
http://community.csdn.net/Expert/topic/4832/4832629.xml?temp=.4810602

想知道,类似的需求应该怎么实现比较好

17,377

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 基础和管理
社区管理员
  • 基础和管理社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧