2009-08-10 18 views
56

En MySQL puedo usar la función RAND(), ¿hay alguna alternativa en SQLite 3?SQLite - ORDER BY RAND()

+0

Pregunta relacionada: http://stackoverflow.com/questions/2171578/seeding-sqlite-random –

Respuesta

43

usando random():

SELECT foo FROM bar 
    WHERE id >= (abs(random()) % (SELECT max(id) FROM bar)) 
    LIMIT 1; 

EDIT (por QOP): Dado que los documentos en SQLite Autoincrement columnas ed establece que:

El algoritmo de selección ROWID normales descrito anteriormente generará monótonamente crecientes ROWIDs únicas, siempre y cuando no utilice nunca el valor máximo ROWID y nunca se borra la entrada en la tabla con el ROWID más grande. Si alguna vez borra filas, las ROWIDs de pueden ser reutilizadas al crear nuevas filas.

Lo anterior sólo es cierto si usted no tiene una columna INTEGER PRIMARY KEY AUTOINCREMENT (todavía no tendrán ningún problema con INTEGER PRIMARY KEY columnas). De todos modos, esto debería ser más portátil/fiable:

SELECT foo FROM bar 
    WHERE _ROWID_ >= (abs(random()) % (SELECT max(_ROWID_) FROM bar)) 
LIMIT 1; 

ROWID, _ROWID_ y OID son todos los alias de la fila SQLite ID interno.

+2

+1 , Esto es mucho más rápido que las otras opciones siempre que id sea índice. –

+14

Sí, esta solución es más rápida, pero supone que el ID comienza en 1 y no tiene espacios vacíos. De lo contrario, las filas que siguen a las brechas se eligen "aleatoriamente" con más frecuencia que otras filas. –

+2

@Bill, gracias por señalar el problema en mi respuesta – dfa

33

resuelto:

SELECT * FROM table ORDER BY RANDOM() LIMIT 1; 
+8

No estoy de acuerdo. Aquí tenemos dos bits de información, cómo seleccionar un solo registro de forma aleatoria, cómo enumerar todos los registros al azar. Nunca he necesitado hacer ninguna de las dos cosas, pero si lo hago, ahora sé cómo. También sé que MySQL lo diferencia de SQLlite. Una pregunta súper técnica sería más impresionante, pero menos útil. –

+0

Lo primero que pensé fue que no había ninguna función para ordenar los resultados aleatoriamente, o si existiera tal función/función sería considerablemente más oscura, eso es lo que sucede con los disparadores de SQLite, por ejemplo. –

+4

He votado esto porque realmente respondió primero. –

112
SELECT * FROM table ORDER BY RANDOM() LIMIT 1; 
+2

Y para el registro, el límite no tiene que ser 1 si desea ordenar toda la tabla de forma aleatoria y acceder a todas las filas en ese orden aleatorio. – lemontwist

+1

Esto también funcionará si tiene una cláusula WHERE compleja y quiere una fila aleatoria de esa lista filtrada. La respuesta aceptada no es compatible con eso fácilmente. –

+0

Y uno más esto no hay una fila duplicada devuelta en el resultado, esto es lo que necesito (y) –

9

Para un uso mucho mejor rendimiento en esta SQLite:

SELECT * FROM table WHERE id IN (SELECT id FROM table ORDER BY RANDOM() LIMIT x) 

Esto es aplicable a MySQL también. Esto funciona más rápido porque los motores de SQL primero cargan los campos de filas proyectados en la memoria y luego los clasifican, aquí solo cargamos y ordenamos aleatoriamente el campo de id de filas, luego obtenemos X de ellos, y encontramos las filas completas de estos X identificadores que es por defecto indexado.

Cuestiones relacionadas