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

Problema con consulta anidada

Estas en el tema de Problema con consulta anidada en el foro de Bases de Datos General en Foros del Web. Buenas!! Pues tengo un problemilla con una consulta a la base de datos,... A grandes rasgos tengo: * Tabla material (id, nombre) * tabla historial_material ...
  #1 (permalink)  
Antiguo 23/06/2010, 11:53
 
Fecha de Ingreso: enero-2006
Mensajes: 13
Antigüedad: 18 años, 3 meses
Puntos: 0
Problema con consulta anidada

Buenas!! Pues tengo un problemilla con una consulta a la base de datos,... A grandes rasgos tengo:

* Tabla material (id, nombre)
* tabla historial_material (id, idmaterial, fechacreacion, estado)

Cada vez que cambia el estado del material (puede estar ocupado, roto, disponible,...), inserto una linea en la tabla historial_material.

El caso es que quiero sacar una lista de material con su estado actual (me baso en el maximo fechacreacion) y no hay manera :(

Lo ideal sería....

Código MySQL:
Ver original
  1. SELECT m.*, hm.estado FROM MATERIAL m, HISTORIAL_MATERIAL hm
  2. WHERE m.id=hm.idmaterial and hm.id in (
  3. select max(fechacreacion) from HISTORIAL_MATERIAL hm2 where hm2.id = hm.id limit 0,1)

Pero el problema está en que no se puede (en MySQL por lo menos) realizar el limit en una consulta interna. ¿Alguien se le ocurre alguna consulta que pueda funcionar?
  #2 (permalink)  
Antiguo 23/06/2010, 15:23
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años, 1 mes
Puntos: 300
Respuesta: Problema con consulta anidada

Prueba así:
SELECT m.id, m.nombre, t1.estado, t1.fechacreacion FROM MATERIAL m INNER JOIN (SELECT idmaterial, estado, fechacreacion FROM HISTORIAL_MATERIAL ORDER BY fechacreacion DESC)t1 on t1.idmaterial = m.id GROUP BY m.id
  #3 (permalink)  
Antiguo 24/06/2010, 03:16
 
Fecha de Ingreso: enero-2006
Mensajes: 13
Antigüedad: 18 años, 3 meses
Puntos: 0
Respuesta: Problema con consulta anidada

Muchas gracias por tu respuesta! Parece que funciona perfectamente!!

¿podrías explicar un poco el "truco" de esa consulta? Es que me resulta raro al realizar la consulta interna saque todos los valores de la tabla historial, pero despues cuando hace el group by solo coge el primer registro que coincida de la consulta interna ignorando los demas ¿pq pasa eso?
  #4 (permalink)  
Antiguo 24/06/2010, 04:02
 
Fecha de Ingreso: enero-2006
Mensajes: 13
Antigüedad: 18 años, 3 meses
Puntos: 0
Respuesta: Problema con consulta anidada

Cita:
Iniciado por jurena Ver Mensaje
Prueba así:
SELECT m.id, m.nombre, t1.estado, t1.fechacreacion FROM MATERIAL m INNER JOIN (SELECT idmaterial, estado, fechacreacion FROM HISTORIAL_MATERIAL ORDER BY fechacreacion DESC)t1 on t1.idmaterial = m.id GROUP BY m.id
vaya, me he encontrado con otro problema. Resulta que quiero sacar solo el material que este disponible (en mi caso lo he codificado con un int, donde 0 es disponible, 1 ocupado...). Al modificar la consulta para realizar esto, ya no me saca los datos correctos, ya que al tener el select interno todos los registros disponibles, coge los especifique en el where ignorando el orden preestablecido :( ¿alguna sugerencia?
  #5 (permalink)  
Antiguo 24/06/2010, 04:08
 
Fecha de Ingreso: enero-2006
Mensajes: 13
Antigüedad: 18 años, 3 meses
Puntos: 0
Respuesta: Problema con consulta anidada

Cita:
Iniciado por mercucho1 Ver Mensaje
vaya, me he encontrado con otro problema. Resulta que quiero sacar solo el material que este disponible (en mi caso lo he codificado con un int, donde 0 es disponible, 1 ocupado...). Al modificar la consulta para realizar esto, ya no me saca los datos correctos, ya que al tener el select interno todos los registros disponibles, coge los especifique en el where ignorando el orden preestablecido :( ¿alguna sugerencia?
antes lo digo, antes lo saco. He vuelto a realizar otra consulta mas sobre los resultados, quedando así...

Código MySQL:
Ver original
  1.  (SELECT m.id, m.nombre, t1.estado, t1.fechacreacion FROM MATERIAL m INNER JOIN
  2.     (SELECT idmaterial, estado, fechacreacion FROM HISTORIAL_MATERIAL ORDER BY fechacreacion DESC) t1
  3.  on t1.idmaterial = m.id GROUP BY m.id) t2
  4. where t2.estado = 1

Tiene miga la consulta...
  #6 (permalink)  
Antiguo 24/06/2010, 15:00
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años, 1 mes
Puntos: 300
Respuesta: Problema con consulta anidada

SELECT m.id, m.nombre, t1.estado, t1.fechacreacion FROM MATERIAL m INNER JOIN (SELECT idmaterial, estado, fechacreacion FROM HISTORIAL_MATERIAL WHERE estado = 1 ORDER BY fechacreacion DESC)t1 on t1.idmaterial = m.id WHERE t1.estado = 1 GROUP BY m.id

El estado lo buscas dentro, porque reduces el número de registros en la selección y eliminas una subconsulta, aunque luego tienes que volver a introducirlo en el where final, dada el tipo de cruce con INNER JOIN basado sólo en el idmaterial.
El truco sobre el que preguntabas: cuando MySQL agrupa, sólo devuelve el primer registro de los que comparten el elemento agrupado; yo con el order by desc pongo como primero de cada id el que tiene la última fecha, y al agrupar me conserva sólo ese.

Última edición por jurena; 24/06/2010 a las 23:28

Etiquetas: bases-de-datos
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 10:55.