Il primo suggerimento di Pradeep Adiga ORDER BY NEWID(), va bene e qualcosa che ho usato in passato per questo motivo.
Fai attenzione all'uso RAND(): in molti contesti viene eseguito solo una volta per istruzione, quindi ORDER BY RAND()non avrà alcun effetto (poiché ottieni lo stesso risultato da RAND () per ogni riga).
Per esempio:
SELECT display_name, RAND() FROM tr_person
restituisce ogni nome dalla nostra tabella personale e un numero "casuale", che è lo stesso per ogni riga. Il numero varia ogni volta che si esegue la query, ma è lo stesso per ogni riga ogni volta.
Per dimostrare che lo stesso è il caso di RAND()usato in una ORDER BYclausola, provo:
SELECT display_name FROM tr_person ORDER BY RAND(), display_name
I risultati sono ancora ordinati per nome indicando che il campo di ordinamento precedente (quello che si prevede sia casuale) non ha alcun effetto, quindi presumibilmente ha sempre lo stesso valore.
L'ordinamento per NEWID()funziona, tuttavia, perché se NEWID () non fosse sempre rivalutato, lo scopo degli UUID verrebbe interrotto quando si inserivano molte nuove righe in uno stato con identificatori univoci come chiave, quindi:
SELECT display_name FROM tr_person ORDER BY NEWID()
non ordinare i nomi "a caso".
Altro DBMS
Quanto sopra vale per MSSQL (almeno nel 2005 e nel 2008, e se ricordo bene anche il 2000). Una funzione che restituisce un nuovo UUID dovrebbe essere valutata ogni volta in tutti i DBMS NEWID () è sotto MSSQL ma vale la pena verificarlo nella documentazione e / o dai propri test. Il comportamento di altre funzioni con risultati arbitrari, come RAND (), ha maggiori probabilità di variare tra DBMS, quindi controlla di nuovo la documentazione.
Inoltre ho visto l'ordinamento in base a valori UUID ignorati in alcuni contesti poiché il DB presume che il tipo non abbia un ordinamento significativo. Se trovi che questo è il caso esplicito cast dell'UUID in un tipo di stringa nella clausola ordering o avvolgi alcune altre funzioni attorno ad esso come CHECKSUM()in SQL Server (potrebbe esserci anche una piccola differenza di prestazioni da questo poiché l'ordinamento verrà eseguito su valori a 32 bit e non a 128 bit, anche se il vantaggio di questo supera il costo di esecuzione CHECKSUM()per valore prima ti lascio testare).
Nota a margine
Se si desidera un ordinamento arbitrario ma in qualche modo ripetibile, ordinare da un sottoinsieme relativamente incontrollato dei dati nelle righe stesse. Ad esempio, uno di questi o questi restituiranno i nomi in un ordine arbitrario ma ripetibile:
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)
Gli ordini arbitrari ma ripetibili non sono spesso utili nelle applicazioni, anche se possono essere utili nel test se si desidera testare un po 'di codice sui risultati in una varietà di ordini ma si desidera poter ripetere ogni esecuzione allo stesso modo più volte (per ottenere tempi medi) risultati su più esecuzioni o test che una correzione apportata al codice rimuove un problema o un'inefficienza precedentemente evidenziata da un determinato set di risultati di input o solo per verificare che il codice sia "stabile" in quanto restituisce lo stesso risultato ogni volta se inviato gli stessi dati in un determinato ordine).
Questo trucco può anche essere usato per ottenere risultati più arbitrari da funzioni, che non consentono chiamate non deterministiche come NEWID () all'interno del loro corpo. Ancora una volta, questo non è qualcosa che probabilmente sarà utile nel mondo reale ma potrebbe tornare utile se vuoi che una funzione restituisca qualcosa di casuale e "random-ish" sia abbastanza buono (ma fai attenzione a ricordare le regole che determinano quando le funzioni definite dall'utente vengono valutate, cioè di solito solo una volta per riga, oppure i risultati potrebbero non essere quelli previsti / richiesti).
Prestazione
Come sottolinea EBarr, possono esserci problemi di prestazioni con uno qualsiasi dei precedenti. Per più di alcune righe sei quasi garantito di vedere lo spooling dell'output su tempdb prima che il numero richiesto di righe venga letto nel giusto ordine, il che significa che anche se stai cercando la top 10 potresti trovare un indice completo scan (o peggio, table scan) avviene insieme a un enorme blocco di scrittura su tempdb. Pertanto, può essere di vitale importanza, come nella maggior parte delle cose, fare un benchmark con dati realistici prima di utilizzarli in produzione.