我有这样一张桌子:
Id | GroupId | Category
------------------------
1 | 101 | A
2 | 101 | B
3 | 101 | C
4 | 103 | B
5 | 103 | D
6 | 103 | A
........................
Run Code Online (Sandbox Code Playgroud)
我需要GroupId随机选择其中一个.为此,我使用了以下PL/SQL代码块:
declare v_group_count number;
v_group_id number;
begin
select count(distinct GroupId) into v_group_count from MyTable;
SELECT GroupId into v_group_id FROM
(
SELECT GroupId, ROWNUM RN FROM
(SELECT DISTINCT GroupId FROM MyTable)
)
WHERE RN=Round(dbms_random.value(1, v_group_count));
end;
Run Code Online (Sandbox Code Playgroud)
因为我舍入了随机值,所以它将是一个整数值,WHERE RN=Round(dbms_random.value(1, v_group_count))条件必须始终返回一行.一般来说它按预期给我一行.但有时奇怪的是它没有给我任何行,有时会返回两行.这就是为什么它在本节中给出了错误:
SELECT GroupId into v_group_id
Run Code Online (Sandbox Code Playgroud)
谁知道这种行为的原因?
Dav*_*itz 23
round(dbms_random.value(1, v_group_count)) 正在为每一行执行,因此可以选择是否每一行.
PS
获得任何边缘值(例如1和10)的概率是获得任何其他值(例如2到9)的概率的一半.
它是0.0555 ...(1/18)Vs. 0.111 ...(1/9)
[ 1,1.5) --> 1
[1.5,2.5) --> 2
.
.
.
[8.5,9.5) --> 9
[9.5, 10) --> 10
Run Code Online (Sandbox Code Playgroud)
select n,count(*)
from (select round(dbms_random.value(1, 10)) as n
from dual
connect by level <= 100000
)
group by n
order by n
;
Run Code Online (Sandbox Code Playgroud)
N COUNT(*)
1 5488
2 11239
3 11236
4 10981
5 11205
6 11114
7 11211
8 11048
9 10959
10 5519
Run Code Online (Sandbox Code Playgroud)
select n,count(*)
from (select floor(dbms_random.value(1, 11)) as n
from dual
connect by level <= 100000
)
group by n
order by n
;
Run Code Online (Sandbox Code Playgroud)
N COUNT(*)
1 10091
2 10020
3 10020
4 10021
5 9908
6 10036
7 10054
8 9997
9 9846
10 10007
Run Code Online (Sandbox Code Playgroud)
如果您想随机选择一个:
declare v_group_count number;
v_group_id number;
begin
SELECT GroupId into v_group_id
FROM (SELECT DISTINCT GroupId
FROM MyTable
ORDER BY dbms_random.value
) t
WHERE rownum = 1
end;
Run Code Online (Sandbox Code Playgroud)