sql-server - obtener - seleccionar registros aleatorios oracle
Registro aleatorio de una tabla de base de datos(T-SQL) (5)
¿Hay una manera sucinta de recuperar un registro aleatorio de una tabla de servidor sql?
Sí
SELECT TOP 1 * FROM table ORDER BY NEWID()
Explicación
Se NEWID()
un NEWID()
para cada fila y luego la ordena la tabla. Se devuelve el primer registro (es decir, el registro con el GUID "más bajo").
Notas
Los GUID se generan como números pseudoaleatorios desde la versión cuatro:
El UUID de la versión 4 está destinado a generar UUID a partir de números verdaderamente aleatorios o pseudoaleatorios.
El algoritmo es como sigue:
- Establezca los dos bits más significativos (bits 6 y 7) de clock_seq_hi_and_reserved en cero y uno, respectivamente.
- Establezca los cuatro bits más significativos (bits 12 a 15) del campo time_hi_and_version en el número de versión de 4 bits de la Sección 4.1.3.
- Establezca todos los demás bits en valores elegidos aleatoriamente (o pseudoaleatoriamente).
- Un identificador universalmente único (UUID) Espacio de nombres URN - RFC 4122
La alternativa
SELECT TOP 1 * FROM table ORDER BY RAND()
no funcionará como uno pensaría.RAND()
devuelve un único valor por consulta, por lo tanto, todas las filas compartirán el mismo valor.Si bien los valores GUID son pseudoaleatorios, necesitará un PRNG mejor para las aplicaciones más exigentes.
El rendimiento típico es de menos de 10 segundos para alrededor de 1,000,000 de filas, por supuesto, dependiendo del sistema. Tenga en cuenta que es imposible alcanzar un índice, por lo que el rendimiento será relativamente limitado.
¿Hay una manera sucinta de recuperar un registro aleatorio de una tabla de servidor sql?
Me gustaría aleatorizar los datos de mi unidad de prueba, por lo que estoy buscando una manera simple de seleccionar una identificación aleatoria de una tabla. En inglés, la selección sería "Seleccione una identificación de la tabla donde la identificación es un número al azar entre la identificación más baja de la tabla y la identificación más alta de la tabla."
No puedo encontrar una manera de hacerlo sin tener que ejecutar la consulta, probar un valor nulo y luego volver a ejecutar si es nulo.
Ideas?
En tablas más grandes también puede usar TABLESAMPLE
para evitar escanear toda la tabla.
SELECT TOP 1 *
FROM YourTable
TABLESAMPLE (1000 ROWS)
ORDER BY NEWID()
ORDER BY NEWID
se requiere ORDER BY NEWID
para evitar simplemente devolver las filas que aparecen primero en la página de datos.
El número a usar debe elegirse cuidadosamente para el tamaño y la definición de la tabla, y puede considerar la lógica de reintento si no se devuelve ninguna fila. Las matemáticas detrás de esto y por qué la técnica no es adecuada para las tablas pequeñas se discute aquí
Estaba buscando mejorar los métodos que había probado y encontré esta publicación. Me doy cuenta de que es viejo, pero este método no está en la lista. Estoy creando y aplicando datos de prueba; esto muestra el método para "dirección" en un SP llamado con @st (estado de dos caracteres)
Create Table ##TmpAddress (id Int Identity(1,1), street VarChar(50), city VarChar(50), st VarChar(2), zip VarChar(5))
Insert Into ##TmpAddress(street, city, st, zip)
Select street, city, st, zip
From tbl_Address (NOLOCK)
Where st = @st
-- unseeded RAND() will return the same number when called in rapid succession so
-- here, I seed it with a guaranteed different number each time. @@ROWCOUNT is the count from the most recent table operation.
Set @csr = Ceiling(RAND(convert(varbinary, newid())) * @@ROWCOUNT)
Select street, city, st, Right((''00000'' + ltrim(zip)),5) As zip
From ##tmpAddress (NOLOCK)
Where id = @csr
Pruebe también su método para obtener un ID aleatorio entre MIN (Id) y MAX (Id) y luego
SELECT TOP 1 * FROM table WHERE Id >= @yourrandomid
Siempre obtendrá una fila.
Si desea seleccionar datos grandes, la mejor manera que conozco es:
SELECT * FROM Table1
WHERE (ABS(CAST(
(BINARY_CHECKSUM
(keycol1, NEWID())) as int))
% 100) < 10
Fuente: MSDN