Um recurso muito interessante e pouco conhecido da clausula FROM é a opção SAMPLE. Ela deve ser acompanhada de um número entre (0,100), mas nunca nos limites 0 e 100. Este número indica a probabilidade individual de cada linha da tabela retornar na resposta da query. Por exemplo:
select obj_id, object_name
from my_objs sample(10);
Detalhando um pouco, priemiro vou criar uma tabela e verificar o número de linhas.
create sequence my_obj_seq;
create table my_objs as
select my_obj_seq.nextval obj_id, owner, object_name, object_id
from all_objects;
select count(*)
from my_objs;
No meu Oracle retornou 17.900. Agora tente algo simples como:
select obj_id, object_name
from my_objs;
Obviamente todas as linhas da tabela retornarão na resposta. Incluindo o SAMPLE, temos:
select obj_id, object_name
from my_objs sample(10);
E a chance de cada linha estar na resposta é de apenas 10%. Se executar repetidas vezes, o conjunto resposta será diferente a cada execução por que, para cada linha, o Oracle decide inclui-la ou não na resposta. Ou seja, a resposta passa a ser aleatória.
Neste ponto, você executa:
select count(*) from(
select obj_id, object_name
from my_objs sample(10);
E a resposta é 1.755! Opa, mas isto não é 10% de 17.900. Repetindo o mesmo SELECT COUNT(*) a resposta é 1.829! E na terceira vez é 1.793!
Estaria tudo errado? Não deveria ser exatamente 10% do total de linhas na tabela, nesta caso exatos 1.790?
O Oracle está correto. A chance de cada linha estar na resposta é 10%, mas eventualmente haverá mais linhas na resposta - digamos que deram sorte - ou menos linhas - estavam com azar. Se você precisar de um número exato, basta utilizar uma consulta aninhada:
select * from(
select obj_id, object_name
from my_objs sample(100))
where rownum <= 10;
Eu utilizei este recurso para selecionar um subconjunto aleatório de linhas da tabela. Isto fazia parte de um teste que seria repetido diversas vezes, mas era importante que o conjunto de dados fosse diferente a cada execução, afinal seria desnecessário calcular várias vezes o mesmo valor.