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 originalmysql> #Creamos la tabla de usuarios_temp
Query OK, 0 rows affected (0.08 sec)
mysql> #insertamos valores de ejemplo
Query OK, 2 rows affected (0.02 sec)
+-----------+--------+
| idUsuario | nombre |
+-----------+--------+
| 1 | uno |
| 2 | dos |
+-----------+--------+
mysql> #Creamos la tabla de galerias
Query OK, 0 rows affected (0.05 sec)
mysql> #insertamos valores de ejemplo
mysql
> insert into galerias_temp
values (1, 1, 10), (2, 1, 20), (3, 1, 10), (4, 1, 50), (5, 2, 40), (6, 2, 10), (7, 2, 20);
Query OK, 7 rows affected (0.03 sec)
+-----------+-----------+------------+
| idGaleria | idUsuario | puntuacion |
+-----------+-----------+------------+
| 1 | 1 | 10 |
| 2 | 1 | 20 |
| 3 | 1 | 10 |
| 4 | 1 | 50 |
| 5 | 2 | 40 |
| 6 | 2 | 10 |
| 7 | 2 | 20 |
+-----------+-----------+------------+
mysql> #Para obtener las dos galerías mejor posicionadas
-> (
-> SELECT t3.nombre
, T2.idGaleria
, T2.idUsuario
, puntuacion
, -> (
-> FROM galerias_temp T1
WHERE T1.idUsuario
= T2.idUsuario
) Usuario = t3.idUsuario
-> ) T4
where T4.posicion
<= 2 order by T4.idUsuario
, T4.posicion
;
+--------+-----------+------------+
| nombre | idGaleria | puntuacion |
+--------+-----------+------------+
| uno | 4 | 50 |
| uno | 2 | 20 |
| dos | 5 | 40 |
| dos | 7 | 20 |
+--------+-----------+------------+
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.