A primeira sugestão do Pradeep Adiga,, ORDER BY NEWID()
é boa e algo que usei no passado por esse motivo.
Cuidado ao usar RAND()
- em muitos contextos, ele é executado apenas uma vez por instrução, portanto ORDER BY RAND()
não terá efeito (pois você está obtendo o mesmo resultado de RAND () para cada linha).
Por exemplo:
SELECT display_name, RAND() FROM tr_person
retorna cada nome da nossa tabela pessoal e um número "aleatório", que é o mesmo para cada linha. O número varia cada vez que você executa a consulta, mas é o mesmo para cada linha de cada vez.
Para mostrar que o mesmo é o caso de RAND()
usado em uma ORDER BY
cláusula, tento:
SELECT display_name FROM tr_person ORDER BY RAND(), display_name
Os resultados ainda são ordenados pelo nome, indicando que o campo de classificação anterior (aquele que se espera que seja aleatório) não tem efeito, portanto, presumivelmente, sempre tem o mesmo valor.
A ordenação por NEWID()
funciona, no entanto, porque se NEWID () nem sempre fosse reavaliado, a finalidade dos UUIDs seria quebrada ao inserir muitas novas linhas em uma statemnt com identificadores exclusivos, conforme a chave:
SELECT display_name FROM tr_person ORDER BY NEWID()
não pedir os nomes "aleatoriamente".
Outros DBMS
O acima exposto é verdadeiro para o MSSQL (pelo menos em 2005 e 2008, e se bem me lembro de 2000). Uma função que retorne um novo UUID deve ser avaliada sempre que todos os DBMSs NEWID () estiverem no MSSQL, mas vale a pena verificar isso na documentação e / ou nos seus próprios testes. É mais provável que o comportamento de outras funções de resultado arbitrário, como RAND (), varie entre DBMSs; verifique novamente a documentação.
Também vi a ordenação por valores UUID sendo ignorada em alguns contextos, pois o banco de dados assume que o tipo não possui ordenação significativa. Se você achar que esse é o caso, converta explicitamente o UUID para um tipo de seqüência de caracteres na cláusula de ordenação ou agrupe alguma outra função ao redor, como CHECKSUM()
no SQL Server (pode haver uma pequena diferença de desempenho disso também, pois a ordenação será feita em valores de 32 bits e não de 128 bits, embora o benefício disso supere o custo de execução CHECKSUM()
por valor primeiro, deixarei você testar).
Nota
Se você deseja uma ordem arbitrária, mas um tanto repetível, solicite por algum subconjunto relativamente descontrolado dos dados nas próprias linhas. Por exemplo, um ou estes retornarão os nomes em uma ordem arbitrária, mas repetível:
SELECT display_name FROM tr_person ORDER BY CHECKSUM(display_name), display_name -- order by the checksum of some of the row's data
SELECT display_name FROM tr_person ORDER BY SUBSTRING(display_name, LEN(display_name)/2, 128) -- order by part of the name field, but not in any an obviously recognisable order)
Ordens arbitrárias, mas repetíveis, geralmente não são úteis em aplicativos, mas podem ser úteis em testes, se você quiser testar algum código nos resultados em uma variedade de ordens, mas desejar repetir cada execução da mesma maneira várias vezes (para obter um tempo médio resultados em várias execuções ou testar se uma correção feita no código remove um problema ou ineficiência destacado anteriormente por um determinado conjunto de resultados de entrada ou apenas para testar se o seu código é "estável" e retorna o mesmo resultado sempre se enviou os mesmos dados em uma determinada ordem).
Esse truque também pode ser usado para obter resultados mais arbitrários de funções, que não permitem chamadas não determinísticas como NEWID () dentro de seus corpos. Novamente, isso não é algo que provavelmente seja útil no mundo real, mas pode ser útil se você quiser que uma função retorne algo aleatório e "random-ish" seja bom o suficiente (mas tenha cuidado para lembrar as regras que determinam quando as funções definidas pelo usuário são avaliadas, ou seja, geralmente apenas uma vez por linha, ou seus resultados podem não ser o que você espera / exige).
atuação
Como aponta EBarr, pode haver problemas de desempenho com qualquer uma das opções acima. Por mais de algumas linhas, você tem quase a garantia de ver a saída em spool para tempdb antes que o número solicitado de linhas seja lido na ordem correta, o que significa que, mesmo se você estiver procurando pelas 10 principais, poderá encontrar um índice completo A verificação (ou pior, a verificação da tabela) acontece junto com um enorme bloco de gravação no tempdb. Portanto, pode ser de vital importância, como na maioria das coisas, fazer benchmarks com dados realistas antes de usá-los na produção.