Ver Mensaje Individual
  #3 (permalink)  
Antiguo 04/02/2011, 16:21
leonardo_josue
Colaborador
 
Fecha de Ingreso: enero-2007
Ubicación: México
Mensajes: 2.097
Antigüedad: 15 años, 7 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.