Las siguientes soluciones son mucho más rápidas que las de anktastic (el recuento (*) cuesta mucho, pero si puede almacenarlo en caché, entonces la diferencia no debería ser tan grande), que es mucho más rápido que el "orden por random() "cuando tienes una gran cantidad de filas, aunque tienen algunos inconvenientes. (. Es decir, unos supresiones)
Si sus ROWIDs están bien embalados, entonces usted puede hacer lo siguiente (utilizando (select max(rowid) from foo)+1
en lugar de max(rowid)+1
da un mejor rendimiento, como se explica en los comentarios):
select * from foo where rowid = (abs(random()) % (select (select max(rowid) from foo)+1));
Si tiene hoyos, a veces intentarás seleccionar un rowid no existente, y el select devolverá un conjunto de resultados vacío. Si esto no es aceptable, puede proporcionar un valor por defecto de esta manera:
select * from foo where rowid = (abs(random()) % (select (select max(rowid) from foo)+1)) or rowid = (select max(rowid) from node) order by rowid limit 1;
Esta segunda solución no es perfecta: la distribución de probabilidad es más alta en la última fila (la que tiene la más alta rowid), pero si a menudo agrega cosas a la mesa, se convertirá en un objetivo en movimiento y la distribución de probabilidades debería ser mucho mejor.
Sin embargo, otra solución, si a menudo seleccionar cosas al azar de una tabla con una gran cantidad de agujeros, entonces es posible que desee crear una tabla que contiene las filas de la tabla original, ordenados en orden aleatorio:
create table random_foo(foo_id);
entonces, periodicalliy, vuelva a llenar la tabla random_foo
delete from random_foo;
insert into random_foo select id from foo;
Y para seleccionar una fila al azar, se puede usar mi primer método (no hay agujeros aquí). Por supuesto, este último método tiene algunos problemas de concurrencia, pero la reconstrucción de random_foo es una operación de mantenimiento que no es probable que suceda muy a menudo.
Sin embargo, otra forma, que encontré recientemente en un mailing list, es poner un disparador en eliminar para mover la fila con el rowid más grande en la fila eliminada actual, para que no queden agujeros.
Por último, tenga en cuenta que el comportamiento de rowid y un autoincrement clave primaria número entero no es idéntico (con rowid, cuando se inserta una nueva fila, max (rowid) se elige 1, wheras es higest-valor en constante visto + 1 para una clave principal), por lo que la última solución no funcionará con una autoincrementación en random_foo, pero los otros métodos lo harán.
múltiples http://stackoverflow.com/questions/4114940/select-random-rows-in-sqlite –