programing

where 절에서 이상한 임의 동작

skycolor 2023. 7. 11. 21:57
반응형

where 절에서 이상한 임의 동작

다음과 같은 테이블이 있습니다.

     Id | GroupId | Category
     ------------------------
     1  | 101     | A
     2  | 101     | B
     3  | 101     | C
     4  | 103     | B
     5  | 103     | D
     6  | 103     | A
     ........................

나는 그 중 하나를 선택해야 합니다.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;

임의의 값을 반올림했기 때문에 정수 값이 될 것이고,WHERE RN=Round(dbms_random.value(1, v_group_count))조건은 항상 하나의 행을 반환해야 합니다.일반적으로 예상대로 한 줄로 되어 있습니다.그런데 이상하게도 가끔은 행이 없고 가끔은 두 행이 되돌아옵니다.이 섹션에서 오류가 발생하는 이유는 다음과 같습니다.

SELECT GroupId into v_group_id

그 행동의 이유를 아는 사람?

round(dbms_random.value(1, v_group_count))모든 행에 대해 실행되므로 모든 행이 선택되거나 선택되지 않을 수 있습니다.


추신.

ROUND는 잘못된 선택입니다.

에지 값(예: 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

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
;
 

    N   COUNT(*)
    1   5488
    2   11239
    3   11236
    4   10981
    5   11205
    6   11114
    7   11211
    8   11048
    9   10959
    10  5519

dbms_random.value(1,N+1)에서 FLOOR를 사용하는 것이 좋습니다.

    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   
    ;              
                   

N   COUNT(*)
1   10091
2   10020
3   10020
4   10021
5   9908
6   10036
7   10054
8   9997
9   9846
10  10007              

임의로 하나를 선택하려는 경우:

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;

언급URL : https://stackoverflow.com/questions/40610396/strange-random-behavior-in-where-clause

반응형