La primera sugerencia de Pradeep Adiga ORDER BY NEWID()
, está bien y es algo que he usado en el pasado por este motivo.
Tenga cuidado con el uso RAND()
: en muchos contextos, solo se ejecuta una vez por declaración, por ORDER BY RAND()
lo que no tendrá ningún efecto (ya que obtiene el mismo resultado de RAND () para cada fila).
Por ejemplo:
SELECT display_name, RAND() FROM tr_person
devuelve cada nombre de nuestra tabla de personas y un número "aleatorio", que es el mismo para cada fila. El número varía cada vez que ejecuta la consulta, pero es el mismo para cada fila cada vez.
Para mostrar que lo mismo es el caso con RAND()
utilizado en una ORDER BY
cláusula, intento:
SELECT display_name FROM tr_person ORDER BY RAND(), display_name
Los resultados todavía están ordenados por el nombre que indica que el campo de clasificación anterior (el que se espera sea aleatorio) no tiene ningún efecto, por lo que presumiblemente siempre tiene el mismo valor.
NEWID()
Sin embargo, ordenar por funciona, porque si NEWID () no siempre se reevalúa, el propósito de los UUID se rompería al insertar muchas filas nuevas en un estado con identificadores únicos a medida que se introducen, por lo que:
SELECT display_name FROM tr_person ORDER BY NEWID()
no ordenar los nombres "al azar".
Otros DBMS
Lo anterior es cierto para MSSQL (2005 y 2008 al menos, y si recuerdo bien 2000 también). Una función que devuelve un nuevo UUID debe evaluarse cada vez que en todos los DBMS NEWID () esté bajo MSSQL pero vale la pena verificar esto en la documentación y / o por sus propias pruebas. Es más probable que el comportamiento de otras funciones de resultados arbitrarios, como RAND (), varíe entre los DBMS, por lo que debe consultar nuevamente la documentación.
También he visto que se ignora el orden por los valores de UUID en algunos contextos, ya que el DB asume que el tipo no tiene un orden significativo. Si considera que este es el caso, convierta explícitamente el UUID a un tipo de cadena en la cláusula de pedido, o envuelva alguna otra función a su alrededor, como CHECKSUM()
en SQL Server (puede haber una pequeña diferencia de rendimiento de esto también, ya que el pedido se realizará en un valor de 32 bits no uno de 128 bits, aunque si el beneficio de eso supera el costo de ejecución CHECKSUM()
por valor primero, lo dejaré para que lo pruebe).
Nota al margen
Si desea un ordenamiento arbitrario pero algo repetible, ordene por un subconjunto relativamente no controlado de los datos en las filas mismas. Por ejemplo, uno o estos devolverán los nombres en un orden arbitrario pero repetible:
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)
Los pedidos arbitrarios pero repetibles a menudo no son útiles en las aplicaciones, aunque pueden ser útiles en las pruebas si desea probar algún código en los resultados en una variedad de pedidos, pero desea poder repetir cada ejecución de la misma manera varias veces (para obtener el tiempo promedio resultados en varias ejecuciones, o probar que una solución que ha realizado en el código elimina un problema o ineficiencia previamente resaltada por un conjunto de resultados de entrada en particular, o simplemente para probar que su código es "estable", es decir, devuelve el mismo resultado cada vez si se envían los mismos datos en un orden dado).
Este truco también se puede usar para obtener resultados más arbitrarios de las funciones, que no permiten llamadas no deterministas como NEWID () dentro de su cuerpo. Nuevamente, esto no es algo que probablemente sea útil en el mundo real, pero podría ser útil si desea que una función devuelva algo aleatorio y "random-ish" es lo suficientemente bueno (pero tenga cuidado de recordar las reglas que determinan cuando se evalúan las funciones definidas por el usuario, es decir, generalmente solo una vez por fila, o sus resultados pueden no ser lo que espera / requiere).
Actuación
Como señala EBarr, puede haber problemas de rendimiento con cualquiera de los anteriores. Para más de unas pocas filas, está casi garantizado de ver el resultado en cola en tempdb antes de que se vuelva a leer el número solicitado de filas en el orden correcto, lo que significa que incluso si está buscando los 10 principales, puede encontrar un índice completo El escaneo (o peor, escaneo de tabla) ocurre junto con un gran bloque de escritura en tempdb. Por lo tanto, puede ser de vital importancia, como con la mayoría de las cosas, comparar con datos realistas antes de usar esto en la producción.