2008-12-29 22 views
7

¿Cómo combinamos How to request a random row in SQL? y Multiple random values in SQL Server 2005 para seleccionar N filas aleatorias usando una única consulta de SQL puro? Idealmente, me gustaría evitar el uso de procedimientos almacenados si es posible. ¿Esto es posible?¿Cómo seleccionar N filas aleatorias usando SQL puro?

ACLARACIONES:

  1. SQL puro se refiere a lo más cerca posible a la norma ANSI/ISO.
  2. La solución debe ser "lo suficientemente eficiente". Concedido ORDEN POR RAND() podría funcionar pero, como otros han señalado, esto no es factible para las tablas de tamaño mediano.

Respuesta

2

No sé acerca pura ANSI, y no es sencillo, pero se puede retirar mi respuesta a una pregunta similar aquí: Simple Random Samples from a Sql database

+0

No me queda claro cómo implementar lo que propone si la suposición n. ° 3 es falsa (es decir, su tabla tiene agujeros). – Gili

+0

Tiene que volver a escribir la tabla completa para que la suposición n. ° 3 sea verdadera, por lo que es una operación O (n) muy lenta. Cree una nueva tabla con las mismas columnas que la tabla original, y también una columna de identidad para una nueva clave principal que no tendrá espacios vacíos. Luego inserte la tabla original completa en la nueva. – user12861

4

La respuesta a su pregunta es en el segundo link allí:

SELECT * FROM table ORDER BY RAND() LIMIT 1 

Sólo cambia el límite, y/o reescribir para SQL Server:

SELECT TOP 1 * FROM table ORDER BY newid() 

Ahora bien, esta estrictamente responde a su pregunta, pero realmente no debería usar esta solución. Pruébalo en una mesa grande y verás a qué me refiero.

Si su espacio de teclas es secuencial, ya sea sin agujeros o con muy pocos agujeros, y si tiene muy pocos agujeros, no le preocupa que algunas filas tengan una posibilidad ligeramente mayor de ser recogidas que otras, luego puede usar una variación donde calcule qué tecla desea recuperar aleatoriamente, desde 1 hasta la clave más alta en su tabla, y luego recupere la primera fila que tenga una clave igual o superior al número que calculó. Solo necesita la parte "superior a" si su espacio clave tiene agujeros.

Este SQL se deja como un ejercicio para el lector.


Editar: nota, un comentario a otra respuesta aquí menciona que quizá SQL puro decir ANSI SQL estándar. Si ese es el caso, entonces no hay forma, ya que no hay una función aleatoria estandarizada, ni cada motor de base de datos trata la función de números aleatorios de la misma manera. Al menos un motor que he visto "optimiza" la llamada llamándola una vez y simplemente repitiendo el valor calculado para todas las filas.

+0

NEWID() es una mala idea si quieres muestras verdaderamente aleatorias, los GUID tienen mucha estructura. Si no te importa ser realmente aleatorio, adelante. – user12861

1

He aquí una posible solución, que le permiten equilibrar el riesgo de obtener menos de N filas contra un sesgo de muestreo desde el "frente" de la tabla. Esto supone que N es pequeño comparado con el tamaño de la tabla:

select * from table where random() < (N/(select count(1) from table)) limit N; 

Esto generalmente se muestra la mayor parte de la mesa, pero puede volver menos de N filas. Si es aceptable algún sesgo, el numerador puede cambiarse de N a 1.5 * N o 2 * N para que sea muy probable que se devuelvan N filas. Además, si es necesario cambiar aleatoriamente el orden de las filas, no sólo seleccionar un subconjunto aleatorio:

select * from (select * from table 
       where random() < (N/(select count(1) from table)) limit N) 
order by mod(tableid,1111); 

La desventaja de esta solución es que, al menos en PostgreSQL, que utiliza un escaneo secuencial de la tabla.Un numerador más grande acelerará la consulta.

-1

Eso es puede ayudarle a:

SELECT TOP 3 * FROM TABLE ORDER BY NEWID() 
+0

-1, ya cubierto por http://stackoverflow.com/a/396946/14731 y no es Pure SQL (newid() es específico de Microsoft). – Gili

-2

mediante el siguiente código se puede lograr el mismo que están buscando ..

select top 1 * from student1 order by newid() 

valor de cambio de N en la parte superior 1 por lo que recibirá ese número de registros aleatorios.

+0

-1, ya cubierto por stackoverflow.com/a/396946/14731 y no es Pure SQL (newid() es específico de Microsoft). – Gili

Cuestiones relacionadas