varios registros instrucción eliminar ejemplos ejemplo delete definicion comando borrar sql oracle plsql

registros - select count sql server ejemplos



Comportamiento aleatorio extraño en donde cláusula (2)

Tengo una mesa como esta:

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

Necesito seleccionar uno de los GroupId al azar. Para esto he usado el siguiente bloque de código 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;

Como redondeé el valor aleatorio, entonces será un valor entero y la condición WHERE RN=Round(dbms_random.value(1, v_group_count)) debe devolver siempre una fila. En general, me da una fila como se esperaba. Pero extrañamente a veces no me da filas y algunas veces devuelve dos filas. Es por eso que da error en esta sección:

SELECT GroupId into v_group_id

¿Alguien sabe el motivo de ese comportamiento?


Si quieres seleccionar uno al azar:

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;


round(dbms_random.value(1, v_group_count)) se está ejecutando para cada fila, por lo que cada fila puede ser seleccionada o no.

PD

REDONDEAR es una mala elección.

La probabilidad de obtener cualquiera de los valores de borde (por ejemplo, 1 y 10) es la mitad de la probabilidad de obtener cualquier otro valor (por ejemplo, de 2 a 9).
Es 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

Mi recomendación es usar FLOOR en dbms_random.value (1, N + 1)

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