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

Consulta con resultas limitados

Estas en el tema de Consulta con resultas limitados en el foro de Mysql en Foros del Web. Hola, que tal? Tengo un pequeño problema que estuve buscando por todos lados y no encuentro una solucion como la que yo quiero pero acudo ...
  #1 (permalink)  
Antiguo 25/07/2012, 08:35
 
Fecha de Ingreso: septiembre-2010
Mensajes: 19
Antigüedad: 13 años, 6 meses
Puntos: 0
Consulta con resultas limitados

Hola, que tal?

Tengo un pequeño problema que estuve buscando por todos lados y no encuentro una solucion como la que yo quiero pero acudo a ustedes que tienen mucho mas conociemiento en el tema y por ahi conocen alguna forma.

Tengo dos tablas, albumes y fotos, con las siguientes columnas (pongo menos para no hacerlo muy largo)

albumes:
id_album
titulo
descripcion

fotos:
id_foto
id_album
titulo
descripcion

Lo que quiero hacer es traer los los albumes y solo una cantidad de fotos por cada uno, ej. 10.
Entonces tendria que traer solamente 10 fotos por cada album.

Mi solucion que no era la que queria fue traer los albumes y por cada album hacer una consulta y traer las 10 fotos pero no me gusta mucho la idea de hacer tantas llamas si bien solo traigo 5 albumes por pagina para acortar las consultas.

Hay alguna forma de poder hacer esto en una sola consulta?

Espero se haya entendido mi duda y desde ya muchas gracias.
  #2 (permalink)  
Antiguo 25/07/2012, 09:02
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: Consulta con resultas limitados

Cita:
Hay alguna forma de poder hacer esto en una sola consulta?
Tal y como lo has planteado, no. Deberás hacerlo de esa forma.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #3 (permalink)  
Antiguo 25/07/2012, 09:08
 
Fecha de Ingreso: septiembre-2010
Mensajes: 19
Antigüedad: 13 años, 6 meses
Puntos: 0
Respuesta: Consulta con resultas limitados

Me imaginaba gnzsoloyo, queria sacarme la duda con alguien que sepa bien del tema.

Te agradezco la respuesta.
  #4 (permalink)  
Antiguo 25/07/2012, 09:34
Colaborador
 
Fecha de Ingreso: enero-2007
Ubicación: México
Mensajes: 2.097
Antigüedad: 17 años, 2 meses
Puntos: 447
Respuesta: Consulta con resultas limitados

Hola PibeJava:

Hace tiempo discutía con algunos compañeros acerca de un problema similar, les propuse una solución que igual te puede servir. supongamos que tenemos la siguiente información:

Código MySQL:
Ver original
  1. mysql> SELECT * FROM albumes;
  2. +----------+------------+-------------+
  3. | id_album | titulo     | descripcion |
  4. +----------+------------+-------------+
  5. |        1 | Album Uno  | Desc Uno    |
  6. |        2 | Album Dos  | Desc Dos    |
  7. |        3 | Album Tres | Desc Tres   |
  8. +----------+------------+-------------+
  9. 3 rows in set (0.00 sec)
  10.  
  11. mysql> SELECT * FROM fotos;
  12. +---------+----------+---------+----------------+
  13. | id_foto | id_album | titulo  | descripcion    |
  14. +---------+----------+---------+----------------+
  15. |       1 |        1 | Foto 1  | Foto 1-Album 1 |
  16. |       2 |        1 | Foto 2  | Foto 2-Album 1 |
  17. |       3 |        1 | Foto 3  | Foto 3-Album 1 |
  18. |       4 |        2 | Foto 4  | Foto 1-Album 2 |
  19. |       5 |        2 | Foto 5  | Foto 2-Album 2 |
  20. |       6 |        2 | Foto 6  | Foto 3-Album 2 |
  21. |       7 |        3 | Foto 7  | Foto 1-Album 3 |
  22. |       8 |        3 | Foto 8  | Foto 2-Album 3 |
  23. |       9 |        3 | Foto 9  | Foto 3-Album 3 |
  24. |      10 |        3 | Foto 10 | Foto 4-Album 3 |
  25. +---------+----------+---------+----------------+
  26. 10 rows in set (0.01 sec)

Supongamos ahora que queremos mostrar sólo las 2 primeras fotos para cada album. La idea es simular la función ROW_NUMBER de Oracle o SQL Server para numerar cada registro... hay muchas formas de hacerlo, pero para este ejemplo lo hacemos con un COUNT (más información en la liga):

http://www.artfulsoftware.com/infotree/queries.php#1098

de esta forma quedaría una consulta así:

Código MySQL:
Ver original
  1. mysql> SELECT F1.id_foto, F1.id_album, COUNT(*) AS row_number
  2.     ->    FROM fotos F1
  3.     ->    INNER JOIN
  4.     ->      fotos F2 ON F1.id_album = F2.id_album AND
  5.     ->      F1.id_foto >= F2.id_foto
  6.     ->    GROUP BY F1.id_album, F1.id_foto;
  7. +---------+----------+------------+
  8. | id_foto | id_album | row_number |
  9. +---------+----------+------------+
  10. |       1 |        1 |          1 |
  11. |       2 |        1 |          2 |
  12. |       3 |        1 |          3 |
  13. |       4 |        2 |          1 |
  14. |       5 |        2 |          2 |
  15. |       6 |        2 |          3 |
  16. |       7 |        3 |          1 |
  17. |       8 |        3 |          2 |
  18. |       9 |        3 |          3 |
  19. |      10 |        3 |          4 |
  20. +---------+----------+------------+
  21. 10 rows in set (0.03 sec)

Con esta consulta, simplemente filtramos los registros que tengan un row_number > 2... al utilizar una función COUNT(*) lo podemos hacer con una sentencia HAVING COUNT(*) <= 2. El resto sería simplemente hacer los JOIN's, incluyendo esta nueva tabla para filtrar la información, es decir, algo como esto:

Código MySQL:
Ver original
  1. mysql> SELECT
  2.     -> A.id_album, A.titulo, A.descripcion,
  3.     -> F.id_foto, F.titulo, F.descripcion
  4.     -> FROM albumes A
  5.     -> INNER JOIN fotos F ON A.id_album = F.id_album
  6.     -> INNER JOIN
  7.     ->   (SELECT F1.id_foto, F1.id_album, COUNT(*) AS row_number
  8.     ->    FROM fotos F1
  9.     ->    INNER JOIN
  10.     ->      fotos F2 ON F1.id_album = F2.id_album AND
  11.     ->      F1.id_foto >= F2.id_foto
  12.     ->    GROUP BY F1.id_album, F1.id_foto
  13.     ->    HAVING COUNT(*) <= 2) T
  14.     ->  ON T.id_foto = F.id_foto AND T.id_album = F.id_album;
  15. +----------+------------+-------------+---------+--------+----------------+
  16. | id_album | titulo     | descripcion | id_foto | titulo | descripcion    |
  17. +----------+------------+-------------+---------+--------+----------------+
  18. |        1 | Album Uno  | Desc Uno    |       1 | Foto 1 | Foto 1-Album 1 |
  19. |        1 | Album Uno  | Desc Uno    |       2 | Foto 2 | Foto 2-Album 1 |
  20. |        2 | Album Dos  | Desc Dos    |       4 | Foto 4 | Foto 1-Album 2 |
  21. |        2 | Album Dos  | Desc Dos    |       5 | Foto 5 | Foto 2-Album 2 |
  22. |        3 | Album Tres | Desc Tres   |       7 | Foto 7 | Foto 1-Album 3 |
  23. |        3 | Album Tres | Desc Tres   |       8 | Foto 8 | Foto 2-Album 3 |
  24. +----------+------------+-------------+---------+--------+----------------+
  25. 6 rows in set (0.06 sec)

Observa que sólo te trae dos fotos por cada album, que creo que es lo que pretendes...

Sale un vistazo, creo que te puede servir. Si tienes problemas para entender alguna parte de la consulta me la comentas y lo vemos.

Saludos
Leo.
  #5 (permalink)  
Antiguo 25/07/2012, 09:36
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: Consulta con resultas limitados

El problema es que habría que iterar los identificadores de los álbumes para poder obtener los de las fotos, y como eso implicaría crear dinamicamente un conjunto de subconsultas unidas con UNION, la cosa se volvería una locura... si es que funciona.
Existe una posibilidad, pero es bastante complicada: Usar Stored procedures, con tablas de tipo TEMPORARY y cursores sobre los álbumes.
Podría funcionar, pero es una codificación algo rebuscada para quien no tenga práctica en SP.
(Je, je... este Leo, anda siempre un pasito cerca mío :D)
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #6 (permalink)  
Antiguo 25/07/2012, 09:52
Colaborador
 
Fecha de Ingreso: enero-2007
Ubicación: México
Mensajes: 2.097
Antigüedad: 17 años, 2 meses
Puntos: 447
Respuesta: Consulta con resultas limitados



Parecemos caballos en la recta final, con Foto Finish... lo bueno es que corremos hacia el mismo lado. Malo sería que fuéramos como dos trenes sobre la misma vía, pero yendo uno en contra del otro.

Saludos
Leo.
  #7 (permalink)  
Antiguo 25/07/2012, 10:32
 
Fecha de Ingreso: septiembre-2010
Mensajes: 19
Antigüedad: 13 años, 6 meses
Puntos: 0
Respuesta: Consulta con resultas limitados

leonardo_josue! La verdad que no tengo palabras para agradecerte la ayuda. Lo probe y anda perfecto. Tendria que enviarte un buen vino o alfajores como agradecimiento por el tiempo que te tomaste en mostrarme como es. Aparte me hiciste dar cuenta cuenta lo lejos que estoy de ese tipo de cosas, ni siquiera entiendo el 2º INNER JOIN. Pero ya lo estoy estudiando.

Otra vez gracias a vos y a gnzsoloyo por la atencion.
  #8 (permalink)  
Antiguo 25/07/2012, 11:34
Colaborador
 
Fecha de Ingreso: enero-2007
Ubicación: México
Mensajes: 2.097
Antigüedad: 17 años, 2 meses
Puntos: 447
Respuesta: Consulta con resultas limitados



La verdad es que no me caería nada mal una buena botella de vino o unos deliciosos Alfajores, pero como estoy en mi México Lindo y Querido te acompañarte con unos buenos tequilas y unos dulces de leche...

La consulta en realidad no es tan compleja, es solo cuestión de tomar algo de la experiencia con Oracle y SQL Server y aplicarla a MySQL. Como te comenté, el truco esta en simular la función ROW_NUMBER para aplicarla a MySQL... hay muchas maneras de hacerlo... la liga que te puse muestra dos de ellas que desde mi punto de vista son de las más sencillas (la página tiene muchísimos ejemplos de estas y otras consultas avanzadas que estoy seguro que te podrían servir en un futuro, deberías tomarte un tiempo largo en estudiar su contenido).

Para entender un poco mejor la consulta, lo que estás haciendo sería una especie de "producto cartesiano" entre la misma tabla... utilizas un INNER JOIN sobre la misma tabla, por naturaleza, el INNER JOIN sirve para asociar uno a uno dos registros, sin embargo observa que en la cláusula ON se utiliza una condición >=, por lo que en realidad estarías uniendo de uno a muchos... si ejecutas esta consulta, sin el COUNT(*) ni el GROUP BY te darás cuenta de cómo se hace esta unión:

Código MySQL:
Ver original
  1. mysql> SELECT
  2.     -> F1.id_album id_album_f1, F1.id_foto id_foto_f1,
  3.     -> F2.id_album id_album_f2, F2.id_foto id_foto_f2
  4.     -> FROM fotos F1
  5.     -> INNER JOIN
  6.     ->   fotos F2 ON F1.id_album = F2.id_album AND
  7.     ->   F1.id_foto >= F2.id_foto
  8.     -> ORDER BY F1.id_album, F1.id_foto;
  9. +-------------+------------+-------------+------------+
  10. | id_album_f1 | id_foto_f1 | id_album_f2 | id_foto_f2 |
  11. +-------------+------------+-------------+------------+
  12. |           1 |          1 |           1 |          1 |
  13. |           1 |          2 |           1 |          1 |
  14. |           1 |          2 |           1 |          2 |
  15. |           1 |          3 |           1 |          1 |
  16. |           1 |          3 |           1 |          2 |
  17. |           1 |          3 |           1 |          3 |
  18. |           2 |          4 |           2 |          4 |
  19. |           2 |          5 |           2 |          4 |
  20. |           2 |          5 |           2 |          5 |
  21. |           2 |          6 |           2 |          6 |
  22. |           2 |          6 |           2 |          4 |
  23. |           2 |          6 |           2 |          5 |
  24. |           3 |          7 |           3 |          7 |
  25. |           3 |          8 |           3 |          7 |
  26. |           3 |          8 |           3 |          8 |
  27. |           3 |          9 |           3 |          7 |
  28. |           3 |          9 |           3 |          8 |
  29. |           3 |          9 |           3 |          9 |
  30. |           3 |         10 |           3 |          7 |
  31. |           3 |         10 |           3 |          8 |
  32. |           3 |         10 |           3 |          9 |
  33. |           3 |         10 |           3 |         10 |
  34. +-------------+------------+-------------+------------+
  35. 22 rows in set (0.14 sec)

Observa que el número de registros de la tabla F2 con que se relaciona cada registro de la tabla F1 es justamente la posición que le corresponde, utilizando entonces la función COUNT(*) y el GROUP BY obtienes el resultado deseado. Espero que esto te ayude a entender un poco mejor la consulta.

Saludos y Salud!
Leo.
  #9 (permalink)  
Antiguo 25/07/2012, 12:34
 
Fecha de Ingreso: septiembre-2010
Mensajes: 19
Antigüedad: 13 años, 6 meses
Puntos: 0
Respuesta: Consulta con resultas limitados

Podemos intercambiar cultura gastronomica leonardo_josue porque de bases de datos tengo que sentarme a leer y aprender mucho todavia para poder intercambiar algo con ustedes. Ahora me quedo mas claro el INNER JOIN, de esa forma no lo habia implementado nunca.

Gracias por el tiempo.

Etiquetas: albumes, fotos, limite
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 06:14.