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

Obtener X registros

Estas en el tema de Obtener X registros en el foro de Mysql en Foros del Web. Saludos a todos. Y pido disculpas por lo poco claro del título. Mi consulta es un poco compleja y no se como resumirlo de una ...
  #1 (permalink)  
Antiguo 04/02/2011, 03:37
 
Fecha de Ingreso: agosto-2004
Mensajes: 312
Antigüedad: 20 años, 3 meses
Puntos: 0
Obtener X registros

Saludos a todos.
Y pido disculpas por lo poco claro del título. Mi consulta es un poco compleja y no se como resumirlo de una manera clara.

Tengo una BBDD en la que guardo usuarios y galerias. Cada usuario tiene una puntuacion y quiero mostrar 3 galerias por usuario ordenadas por la puntuacion del usuario, de manera que si un usuario tiene 20 galerias no aparezcan primero las veinte de este usuario, luego otras quince de otro, sino como máximo tres galerias del usuario mejor puntuado, luego otras tres del siguiente,... y así hasta el último. Cada galeria muestra una breve información del usuario.
Mi sentencia SQL es la siguiente:
Código MySQL:
Ver original
  1. SELECT G. * , E. *
  2. FROM galerias AS G INNER JOIN entidades AS E ON E.id_entidad = G.id_entidad
  3. WHERE G.activo =1
  4. ORDER BY E.puntos_totales DESC
He probado a introducir LIMIT, pero eso me limita el número de registros que aparecen.

Tal vez me estoy complicando la vida y es más sencillo hacer dos consultas. Una que me muestre las entidades y por cada entidad muestro los porfolios que necesito mediante LIMIT (estoy programando en Php) Pero se me ha colado el tratar de hacerlo todo en una.

Si alguien tiene una solución, le estaría muy agradecido.

Un saludo
  #2 (permalink)  
Antiguo 04/02/2011, 08:17
 
Fecha de Ingreso: diciembre-2010
Mensajes: 8
Antigüedad: 13 años, 11 meses
Puntos: 0
Mensaje Respuesta: Obtener X registros

Creo que puedes plantear de varias formas: una sería ...

Haces una primera consulta (SELECT) de los usuarios ordenados por puntuación y mediante un for() (en php) realizas consultas (SELECT) a la tabla de las galerías con un LIMIT 0,3 (para mostrar sólo 3 galerías) y con la sentencia WHERE en la que id_entidad de la tabla galerías sea igual al contenido del array de la primera consulta.

O sea:

SELECT * FROM entidades ....
(obtener el resultado de la consulta en un array: $r_ent)

Presentar datos del usuario

Recorremos el array ...

for($i = 0; $i < count($r_ent); $i++)
{
SELECT * FROM galerIas WHERE id_entidad = '".$r_ent[$i]['id_entidad']."'";
(obtener el resultado de la consulta en un array: $r_gal)

Presentar los datos de las galerías
}
  #3 (permalink)  
Antiguo 04/02/2011, 16:21
Colaborador
 
Fecha de Ingreso: enero-2007
Ubicación: México
Mensajes: 2.097
Antigüedad: 17 años, 10 meses
Puntos: 447
Respuesta: Obtener X registros

Hola chemon, hace algún tiempo tuve necesidad de hacer algo parecido a lo que quieres hacer. después de mucho buscar encontré un ejemplo que me sirvió, checa esta liga:

Simular row_number

En mi caso la situación era más o menos así:

Código:
Tabla Usuarios
idUsuario|nombre
---------------------------
1|uno
2|dos

Tabla Galerias
idGaleria|idUsuario|puntuacion
---------------------------------------
1|1|10
2|1|20
3|1|10
4|1|50
5|2|40
6|2|10
7|2|20
El objetivo era mostrar las dos galerías mejor puntuadas para cada usuario. Aquí está la implementación que tuve que hacer:

Código:
select nombre, idGaleria, puntuacion from 
(
	SELECT t3.nombre, T2.idGaleria, T2.idUsuario, puntuacion, 
	FIND_IN_SET(T2.puntuacion, 
	( 
		SELECT GROUP_CONCAT(puntuacion ORDER BY puntuacion DESC) 
		FROM galerias_temp T1 WHERE T1.idUsuario = T2.idUsuario ) 
	) AS posicion FROM galerias_temp T2 inner join usuarios_temp t3 on T2.idUsuario = t3.idUsuario
) T4 where T4.posicion <= 2 order by T4.idUsuario, T4.posicion
Parece algo complicado, pero aquí está la implementación paso a paso de lo que tuve que hacer.

Código MySQL:
Ver original
  1. mysql> #Creamos la tabla de usuarios_temp
  2. mysql> create table usuarios_temp (idUsuario int, nombre varchar(10));
  3. Query OK, 0 rows affected (0.08 sec)
  4.  
  5. mysql> #insertamos valores de ejemplo
  6. mysql> insert into usuarios_temp values (1, 'uno'), (2, 'dos');
  7. Query OK, 2 rows affected (0.02 sec)
  8. Records: 2  Duplicates: 0  Warnings: 0
  9.  
  10. mysql> select * from usuarios_temp;
  11. +-----------+--------+
  12. | idUsuario | nombre |
  13. +-----------+--------+
  14. |         1 | uno    |
  15. |         2 | dos    |
  16. +-----------+--------+
  17. 2 rows in set (0.00 sec)
  18.  
  19. mysql> #Creamos la tabla de galerias
  20. mysql> create table galerias_temp (idGaleria int, idUsuario int, puntuacion int);
  21. Query OK, 0 rows affected (0.05 sec)
  22.  
  23. mysql> #insertamos valores de ejemplo
  24. mysql> insert into galerias_temp values (1, 1, 10),  (2, 1, 20), (3, 1, 10), (4,
  25.  1, 50), (5, 2, 40), (6, 2, 10), (7, 2, 20);
  26. Query OK, 7 rows affected (0.03 sec)
  27. Records: 7  Duplicates: 0  Warnings: 0
  28.  
  29. mysql> select * from galerias_temp;
  30. +-----------+-----------+------------+
  31. | idGaleria | idUsuario | puntuacion |
  32. +-----------+-----------+------------+
  33. |         1 |         1 |         10 |
  34. |         2 |         1 |         20 |
  35. |         3 |         1 |         10 |
  36. |         4 |         1 |         50 |
  37. |         5 |         2 |         40 |
  38. |         6 |         2 |         10 |
  39. |         7 |         2 |         20 |
  40. +-----------+-----------+------------+
  41. 7 rows in set (0.00 sec)
  42.  
  43. mysql> #Para obtener las dos galerías mejor posicionadas
  44. mysql> select nombre, idGaleria, puntuacion from
  45.     -> (
  46.     ->  SELECT t3.nombre, T2.idGaleria, T2.idUsuario, puntuacion,
  47.     ->  FIND_IN_SET(T2.puntuacion,
  48.     ->  (
  49.     ->          SELECT GROUP_CONCAT(puntuacion ORDER BY puntuacion DESC)
  50.     ->          FROM galerias_temp T1 WHERE T1.idUsuario = T2.idUsuario )
  51.     ->  ) AS posicion FROM galerias_temp T2 inner join usuarios_temp t3 on T2.id
  52. Usuario = t3.idUsuario
  53.     -> ) T4 where T4.posicion <= 2 order by T4.idUsuario, T4.posicion;
  54.  
  55. +--------+-----------+------------+
  56. | nombre | idGaleria | puntuacion |
  57. +--------+-----------+------------+
  58. | uno    |         4 |         50 |
  59. | uno    |         2 |         20 |
  60. | dos    |         5 |         40 |
  61. | dos    |         7 |         20 |
  62. +--------+-----------+------------+
  63. 4 rows in set (0.00 sec)

Creo que sería mucho más eficiente que tener que utilizar un for y hacer consultas independientes, ya que el número de consultas que tendías que hacer a la bd es igual al número de usuarios que tengas. Con la implementación que pongo pues sólo tendrías que hacer unas sola consulta y obtendrías el resultado esperado.

Dale un vistazo a ver si puedes adaptar el ejemplo a lo que necesitas hacer.

saludos
Leo.
  #4 (permalink)  
Antiguo 05/02/2011, 05:53
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años, 7 meses
Puntos: 300
Respuesta: Obtener X registros

Leonardo_josue,
creo que esta es una buena contribución que merece aparecer en las FAQ. Con una redacción más general y nombres de campo menos específicos estaría bien, y te animo a hacerlo.
  #5 (permalink)  
Antiguo 07/02/2011, 03:03
 
Fecha de Ingreso: agosto-2004
Mensajes: 312
Antigüedad: 20 años, 3 meses
Puntos: 0
Respuesta: Obtener X registros

Saludos a todos

Me inclino por la solución que me planteas leonardo_josue. Lo que ocurre es que el servidor donde tengo que implementarlo tiene una versión antigua y no se como funcionará. Parece que es la mas optima. Si no consigo que me funcione tendré que probar con los bucles anidados, que como bien dices, es menos optimo.

gracias a todos por vuestros aportes. Con las opciones que me habeis planteado continuaré investigando.

Un saludo

Etiquetas: registros
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 05:00.