Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Mysql »

Consultas "aleatorias"

Estas en el tema de Consultas "aleatorias" en el foro de Mysql en Foros del Web. Hola, a ver cómo os lo explico. Estoy intentando (por cuestiones que no vienen al caso y son largas de explicar pero tienen q ser ...
  #1 (permalink)  
Antiguo 29/01/2014, 04:59
Avatar de humanista  
Fecha de Ingreso: abril-2005
Mensajes: 878
Antigüedad: 19 años
Puntos: 15
Consultas "aleatorias"

Hola, a ver cómo os lo explico.

Estoy intentando (por cuestiones que no vienen al caso y son largas de explicar pero tienen q ser así) buscar la forma de EMPEZAR a hacer una consulta SELECT en un punto aleatorio de la BD y que desde este punto saque todos los registros de la BD.

Para muestra un ejemplo. Imaginemos una esfera de un reloj. Tenemos que sacar los 12 registros con un SELECT pero tenemos que ordenar (o empezar a leer la BD) por un registro elegido al azar, pongamos el 3.

Entonces leería 3, 4, 5 ... 11, 12, 1, y 2

Si el rgto. aleatorio la próxima vez es el 9, leería en este orden:

9, 10, 11, 12, 1, 2... 7, y 8

Mi BD tiene una PK autonumérica. ¿cómo se podría hacer?

Ya sé que es una cosa bastante rara, quizá no tiene lógica o quizá sí...
  #2 (permalink)  
Antiguo 29/01/2014, 06:27
 
Fecha de Ingreso: septiembre-2008
Ubicación: Valencia
Mensajes: 160
Antigüedad: 15 años, 7 meses
Puntos: 2
Respuesta: Consultas "aleatorias"

Lógica la tendrá o no dependiendo de para lo que lo uses.

Supongo que quieres extraer todos los datos de una misma tabla.

Lo que deberás hacer es un seguido de sentencias SQL si quieres sacar el número aleatorio dentro a la vez y no es un valor que se pasa desde otra aplicación. Luego sería ahcer que te devuelva todos los valores iguales y mayores a esa ID y unes la consulta con un UNION a otra que te devuelva los menores.

Para sacar un valor aleatorio para una consulta debes usar CAST(min_id + RAND() * max_id AS UNSIGNED) creando una variable temporal que usar después.

Aquí te dejo el código que resolvería la consulta. Los valores máximos y mínimos si varían seŕia cosa de hacer previamente consultas para que devuelvan el valor máximo y mínimo, y los guardas en otras variables, eso o haces unas subconsultas, yo te lo voy a poner suponiendo que siempre serán constantes.

Código:
SET @nAleatorio = CAST(valor_minimo + RAND()*(valor_maximo - valor_minimo) AS UNSIGNED);

(SELECT * FROM tu_tabla WHERE ID >= @nAleatorio) UNION (SELECT * FROM tu_tabla WHERE ID < @nAleatorio) ;
Espero que esto te sirva para algo, un saludo.
__________________
Siempre inmerso en nuevos proyectos.

Cuando estoy activo puedes verme en //LiveCoding

Última edición por Oracles; 29/01/2014 a las 07:22
  #3 (permalink)  
Antiguo 29/01/2014, 13:15
Avatar de nup_  
Fecha de Ingreso: noviembre-2010
Mensajes: 265
Antigüedad: 13 años, 5 meses
Puntos: 32
Respuesta: Consultas "aleatorias"

hola:

si lo q quieres es extraer una fila aleatoria de tu tabla, hay una forma muy sencilla de hacerlo:

Código MySQL:
Ver original
  1. SELECT t.*, RAND() as r
  2. FROM tabla t

la idea es "asignarle" a cada fila un número aleatorio
ordenar por ese número
seleccionar la primera fila

slds;

nup_
  #4 (permalink)  
Antiguo 30/01/2014, 13:01
Colaborador
 
Fecha de Ingreso: enero-2007
Ubicación: México
Mensajes: 2.097
Antigüedad: 17 años, 3 meses
Puntos: 447
Respuesta: Consultas "aleatorias"

Hola Humanista.

En realidad tu consulta no es del todo "aleatorioa"... si entendí correctamente lo que quieres es a partir de un id aleatorio ordenar los registros presentando primeramente todos aquellos cuyo ID sea mayor o igual a ese numero aleatorio y una vez que llegues al último de los id's, listar aquellos registros menores al número aleatorio... ¿es correcto como entiendo el problema?, si es así entonces debes hacerlo por partes:

Para el ejemplo voy a considerar la siguiente tabla:

Código MySQL:
Ver original
  1. mysql> SELECT * FROM tabla;
  2. +------+-------------+
  3. | id   | descripcion |
  4. +------+-------------+
  5. |    1 | uno         |
  6. |    2 | dos         |
  7. |    3 | tres        |
  8. |    4 | cuatro      |
  9. |    5 | cinco       |
  10. |    6 | seis        |
  11. |    7 | siete       |
  12. |    8 | ocho        |
  13. |    9 | nueve       |
  14. |   10 | diez        |
  15. |   11 | once        |
  16. |   12 | doce        |
  17. +------+-------------+
  18. 12 rows in set (0.00 sec)

Ahora bien, el procedimiento sería el siguiente:

PRIMER PASO: determinar un número aleatorio entre 1 y el valor máximo de tu tabla, en este caso el número 12... hay varias formas de obtener un aleatorio entre un rango determinado, una de estas sería así:

Código MySQL:
Ver original
  1. mysql> SET @aleatorio = FLOOR(RAND() * 12 + 1);
  2. Query OK, 0 rows affected (0.00 sec)
  3.  
  4. mysql> SELECT @aleatorio;
  5. +------------+
  6. | @aleatorio |
  7. +------------+
  8. |          5 |
  9. +------------+
  10. 1 row in set (0.00 sec)


SEGUNDO PASO: Ahora, con esta variable @aleatorio, deberías presentar primero los id's del 5 al 12 y después los id's del 1 al 4, esto lo harías con un ORDER BY condicional:

Código MySQL:
Ver original
  1. mysql> SELECT * FROM tabla
  2.     -> ORDER BY IF (id >= @aleatorio, 0, 1), id;
  3. +------+-------------+
  4. | id   | descripcion |
  5. +------+-------------+
  6. |    5 | cinco       |
  7. |    6 | seis        |
  8. |    7 | siete       |
  9. |    8 | ocho        |
  10. |    9 | nueve       |
  11. |   10 | diez        |
  12. |   11 | once        |
  13. |   12 | doce        |
  14. |    1 | uno         |
  15. |    2 | dos         |
  16. |    3 | tres        |
  17. |    4 | cuatro      |
  18. +------+-------------+
  19. 12 rows in set (0.00 sec)

Si vuelves a ejecutar las consultas, obtendrás otro resultado distinto:

Código MySQL:
Ver original
  1. mysql> SET @aleatorio = FLOOR(RAND() * 12 + 1);
  2. Query OK, 0 rows affected (0.00 sec)
  3.  
  4. mysql> SELECT @aleatorio;
  5. +------------+
  6. | @aleatorio |
  7. +------------+
  8. |         10 |
  9. +------------+
  10. 1 row in set (0.00 sec)
  11.  
  12. mysql> SELECT * FROM tabla
  13.     -> ORDER BY IF (id >= @aleatorio, 0, 1), id;
  14. +------+-------------+
  15. | id   | descripcion |
  16. +------+-------------+
  17. |   10 | diez        |
  18. |   11 | once        |
  19. |   12 | doce        |
  20. |    1 | uno         |
  21. |    2 | dos         |
  22. |    3 | tres        |
  23. |    4 | cuatro      |
  24. |    5 | cinco       |
  25. |    6 | seis        |
  26. |    7 | siete       |
  27. |    8 | ocho        |
  28. |    9 | nueve       |
  29. +------+-------------+
  30. 12 rows in set (0.00 sec)

Checa el script para ver si es más o menos lo que necesitas.

Saludos
Leo
  #5 (permalink)  
Antiguo 04/02/2014, 08:20
Avatar de humanista  
Fecha de Ingreso: abril-2005
Mensajes: 878
Antigüedad: 19 años
Puntos: 15
Respuesta: Consultas "aleatorias"

Vaya, veo que las respuestas son muy elaboradas.

Al final usando el comando RAND() "a secas" me ha servido. Me he dado cuenta de que no necesitaba leer toda la tabla de forma correlativa sino me valía con una lectura aleatoria "total", es decir que lea toda la tabla pero no importa el orden, la cuestión es que no empezara a leer siempre por el mismo sitio.

Etiquetas: registro, select
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 09:01.