quarta-feira, 7 de abril de 2010

Retorna registros randômicos entre um grupo de registros

Hi!

Abaixo segue um exemplo bem interessante onde dentro de um grupo de registros é escolhido um registro aleatório.  Note que além da função DBMS_RANDOM, são utilizadas as funções RANK e OVER.
Em nossa tabela exemplo, teremos os seguintes dados:

Tabela: teste_random

Nome    Numero

======  ======
Felipe  1
Felipe  2
Felipe  3
Thiago  1
Thiago  2
Thiago  3
Edna    1

Segue SCRIPT para a criação da tabela e INSERTs:

create table teste_random
( nome   char(6)
 ,numero char(1)
)
/
insert into teste_random
values
('Felipe','1')
/
insert into teste_random
values
('Felipe','2')
/
insert into teste_random
values
('Felipe','3')
/
insert into teste_random
values
('Thiago','1')
/
insert into teste_random
values
('Thiago','2')
/
insert into teste_random
values
('Thiago','3')
/   
insert into teste_random
values
('Edna','1')
/
COMMIT
/


Qual a idéia. Temos 3 registros para o nome “Felipe”, 3 para o nome “Thiago” e 1 registro para o nome “Edna”. Queremos que dentro de um determinado grupo de registros (grupos por nome) seja escolhido um registro aleatório. Exemplo, para o grupo “Felipe”, onde há três registros “Felipe, 1”, “Felipe, 2” e “Felipe, 3”, o programa deve escolher um destes três registros. E faça isso também para os grupos ”Thiago” e “Edna”. No caso do grupo referente ao nome “Edna”, só existe um registro, portanto, sempre vai retornar o mesmo. Quanto aos outros, para cada grupo, em cada execução ele deve trazer um registro aleatoriamente.

Segue o SELECT que fará isto:
select nome, numero
from (
      select nome, numero
            ,rank() over(partition by nome order by numero) rnk
      from   teste_random
     ) a
where  rnk = (select ceil(dbms_random.value(0,(select count(*) from teste_random te2 where te2.nome = a.nome))) from dual)
 


Segue algumas execuções:



Falows!

Um comentário: