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

SELECTs anidados

Estas en el tema de SELECTs anidados en el foro de Mysql en Foros del Web. Hola, quisiera seleccionar al azar unos 30 resultados de los ultimos 60 registros y pensé en anidar dos SELECT pero no me funciona: Cita: SELECT ...
  #1 (permalink)  
Antiguo 03/02/2009, 17:28
Avatar de Italico76  
Fecha de Ingreso: abril-2007
Mensajes: 3.303
Antigüedad: 17 años, 1 mes
Puntos: 292
Pregunta SELECTs anidados

Hola, quisiera seleccionar al azar unos 30 resultados de los ultimos 60 registros y pensé en anidar dos SELECT pero no me funciona:

Cita:
SELECT claves,veces FROM consultas ORDER BY RAND() LIMIT 30 IN (SELECT claves,veces FROM consultas WHERE filtrado=0 ORDER BY fecha ASC LIMIT 60)
y asi tampoco:

Cita:
SELECT claves,veces FROM consultas ORDER BY RAND() LIMIT 30 = (SELECT claves,veces FROM consultas WHERE filtrado=0 ORDER BY fecha ASC LIMIT 60)
El error me lo marca justo en el IN o el =

Alguien sabe como solucionarlo, gracias ?
(pd: como consultas individuales funcionan bien)
__________________
Salu2!

Última edición por Italico76; 06/02/2009 a las 14:30
  #2 (permalink)  
Antiguo 03/02/2009, 20:17
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años
Puntos: 2135
Respuesta: SELECTs anidados

Código sql:
Ver original
  1. SELECT claves,veces FROM consultas WHERE id_clave IN (SELECT id_clave FROM consultas WHERE filtrado=0 ORDER BY dia ASC LIMIT 60) ORDER BY RAND() LIMIT 30

Solo cambia id_clave por tu primary key.

Saludos
  #3 (permalink)  
Antiguo 03/02/2009, 20:43
Avatar de Italico76  
Fecha de Ingreso: abril-2007
Mensajes: 3.303
Antigüedad: 17 años, 1 mes
Puntos: 292
Respuesta: SELECTs anidados

Me da error siempre en el mismo lugar...... en el IN

Alguna forma que involucre solo MySQL para mostrar al azar los ultimos N registros ingresados ? (que seria algo parecido a lo que queria hacer)

Mi intencion es hacer lo mas posible usando el motor MySQL y sin codificar de mas en PHP.

GRACIAS!
__________________
Salu2!
  #4 (permalink)  
Antiguo 03/02/2009, 23:25
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años
Puntos: 2135
Respuesta: SELECTs anidados

Mmm esa subconsulta te debería de funcionar, que versión de MySQL manejas, ya que las SubConsultas estan disponibles desde MySQL 5.

Saludos
  #5 (permalink)  
Antiguo 04/02/2009, 04:03
Avatar de Italico76  
Fecha de Ingreso: abril-2007
Mensajes: 3.303
Antigüedad: 17 años, 1 mes
Puntos: 292
Respuesta: SELECTs anidados

MySQL 5.0.45 (segun phpinfo)

No te preocupes mas...... no estan grave..... hay mil formas de hacer eso con PHP
__________________
Salu2!
  #6 (permalink)  
Antiguo 04/02/2009, 04:39
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años, 1 mes
Puntos: 300
Respuesta: SELECTs anidados

italico76,

prueba esto, pues evitarás el problema del limit en subconsultas. Lo haremos con un inner join.
Código sql:
Ver original
  1. SELECT t1.id, t1.campo, t1.campofecha
  2. FROM tabla t1
  3. INNER JOIN (
  4.  
  5. SELECT id
  6. FROM campo
  7. ORDER BY campofecha DESC
  8. LIMIT 60
  9. )t2 ON t1.id = t2.id
  10. ORDER BY RAND( ) LIMIT 30

El rand() de MySQL no es gran cosa, pero si quieres utilizarlo podrás hacerlo así.
  #7 (permalink)  
Antiguo 06/02/2009, 09:07
Avatar de Italico76  
Fecha de Ingreso: abril-2007
Mensajes: 3.303
Antigüedad: 17 años, 1 mes
Puntos: 292
Respuesta: SELECTs anidados

amigo jurena: gracias! voy a investigar esto de INNER JOIN.... hice una pruebita pero me falló asi que tengo que ponerme a leer ........

gracias de nuevo......
__________________
Salu2!
  #8 (permalink)  
Antiguo 06/02/2009, 10:33
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años, 1 mes
Puntos: 300
Respuesta: SELECTs anidados

Tal vez al adaptar los nombres se produjo algún error, pero en este caso lo probé antes, aunque con nombres creados por mí. Dinos los nombres de las tablas y de los campos implicados y te proporcionaremos alguna sugerencia sobre la sintaxis.
  #9 (permalink)  
Antiguo 06/02/2009, 14:22
Avatar de Italico76  
Fecha de Ingreso: abril-2007
Mensajes: 3.303
Antigüedad: 17 años, 1 mes
Puntos: 292
Respuesta: SELECTs anidados

Jurena: gracias desde ya!!!!!!!!!!! aca la estructura de la tabla:

Cita:
CREATE TABLE `consultas` (
`claves` varchar(100) character set utf8 collate utf8_unicode_ci NOT NULL,
`veces` int(11) NOT NULL default '1',
`ip` varchar(15) collate latin1_general_ci default NULL,
`fecha` date default NULL,
`hora` time default NULL,
`filtrado` tinyint(1) NOT NULL default '0',
PRIMARY KEY (`claves`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
Y lo que queria...... es tomar al azar unos 30 resultados (campo `claves`) de los ultimos 60 en ser introducidos (campo `fecha`)

Tengo la fecha desagregada en fecha y hora como campos separados pero no me interesa algo tan preciso...... solo lo que quiero es mostrar al azar...... entre los ultimos registros pero sin repetir todos los resultados

Muy agradecido........ Pablo

PD: tendrian que tomarse aproximadamente 30 resultados....... donde algunos estan "filtrados" (no se deben mostrar) por eso yo ponia la clausula WHERE filtrado=0 en la consulta mas interna....... pero podria ser la mas externa...... de ultima son pocos los filtrados :)
__________________
Salu2!

Última edición por Italico76; 06/02/2009 a las 14:30
  #10 (permalink)  
Antiguo 07/02/2009, 01:53
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años, 1 mes
Puntos: 300
Respuesta: SELECTs anidados

Italico76,
Esta es mi propuesta:

Código sql:
Ver original
  1. SELECT c.ip, c.claves, c.veces
  2. FROM consultas c
  3. INNER JOIN (
  4.  
  5. SELECT ip
  6. FROM consultas
  7. WHERE filtrado =0
  8. ORDER BY fecha DESC , hora DESC
  9. LIMIT 60
  10. )T1 ON c.ip = t1.ip
  11. ORDER BY RAND( )
  12. LIMIT 30

He usado en el select interior ip como campo porque me parece que es un dato que no se repetirá en los campos, pero tampoco sé si es así. Igualmente he puesto filtrado dentro, lo que quiere decir que te buscará los 60 últimos con filtrado a 0; y luego esos los ordenará al azar y elegirá 30.
Si quieres que seleccione los 60 últimos tengan o no filtrado a 0 y luego que de esos elija 30 con filtrado a 0 tendrías que escribir esto (pero podría ocurrir que hubiera menos de 30, incluso ninguno):

Código sql:
Ver original
  1. SELECT c.ip, c.claves, c.veces
  2. FROM consultas c
  3. INNER JOIN (
  4.  
  5. SELECT ip
  6. FROM consultas
  7. ORDER BY fecha DESC , hora DESC
  8. LIMIT 60
  9. )T1 ON c.ip = t1.ip WHERE c.filtrado =0
  10. ORDER BY RAND( )
  11. LIMIT 30

Prueba y dinos.
Eso si ip no se repite. Si aparece en varios registros de consulta la misma ip, tendríamos que hacer un group by y sacar el max de date (o de la suma en tiempo de date y hora para hacerlo más exacto). Dinos si se repite y te preparamos una propuesta.

Última edición por jurena; 07/02/2009 a las 01:59
  #11 (permalink)  
Antiguo 07/02/2009, 14:16
Avatar de Italico76  
Fecha de Ingreso: abril-2007
Mensajes: 3.303
Antigüedad: 17 años, 1 mes
Puntos: 292
Respuesta: SELECTs anidados

Jurena: amigo..... me ha funcionado de diez! super......diria......

Sin entender mucho..... le hice unos pequeños cambios sobretodo para ajustar el grado de aleatoriedad (pase de 60 a 120 sobre 30)

Cita:
SELECT c.fecha, c.claves, c.veces
FROM consultas c
INNER JOIN (

SELECT claves
FROM consultas
WHERE filtrado =0
ORDER BY fecha DESC
LIMIT 120
)t1 ON c.claves = t1.claves
ORDER BY RAND( )
LIMIT 30
Un millon de gracias si:
__________________
Salu2!
  #12 (permalink)  
Antiguo 08/02/2009, 02:56
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años, 1 mes
Puntos: 300
Respuesta: SELECTs anidados

Me alegro, amigo. Yo no me había dado cuenta de que el campo claves era distinto en cada registro y era el que debías utilizar para el inner join con la consulta. Observa que la consulta que te puse es la misma que la propuesta por GatorV, con la única diferencia de que esta relación entre tabla y consulta mediante inner join no tiene los impedimientos de usar limit en subconsultas, algo que todavía sigue arrastrando MySQL en las versiones que utilizamos.
El cambio hecho es el correcto si quieres que te busque 120 con filtrado = 0, y luego ordene al azar y seleccione los 30 primeros de esos 120 ordenados al azar.
Saludos

Última edición por jurena; 08/02/2009 a las 06:54
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 21:09.