martes, 26 de junio de 2012

Ranking compuesto

Tenemos una tabla con resultados parciales:
  
Tabla Parcial
id
campo1
campo2
...
campo N
Tenemos una tabla con el ranking actual:
 
Tabla Ranking
id
posicion
posicion_anterior
Vamos a actualizar el ranking con la suma de los resultados parciales, guardando además la posición anterior a la actualización para saber cuanto se ha avanzado o retrocedido desde el último recalculo del ranking.

begin;
-- Insertamos los nuevos registros en el ranking
insert into ranking (id,posicion,ant_posicion) select id,999999,999999
from parcial where id not in (select id from ranking);
-- Actualizamos la posición actual y guardamos la anterior
update ranking set posicion_anterior=ranking.posicion,posicion=temporal.posicion
from  (
select rank() over ( order by sum (campo1+
campo2...campoN) desc) as posicion,
sum (
campo1+campo2) as puntos,id
from parcial
group by id) as temporal
where ranking.id = temporal.id;
 
-- Borramos del ranking quien no tenga puntos parciales
delete from ranking where id not in (select id from parcial);
delete from ranking where id in
(select id from rankings.acumulado where
campo1+campo2...campoN=0 );


end;


Tenemos una tabla con los puntos acumulados por equipos de diferentes regiones y divisiones.

 region_id
division
equipo
puntos

Como hacer un ranking de un plumazo
 select region_id,division,rank() over ( partition by region_id,division order by puntos desc) as posicion,id from
(select
region_id,division,id,sum(puntos) as puntos
from rankings.diario group by
region_id,division,id) as temporal;

Enlaces de Interés:

http://www.postgresql.org.es/node/376 (Funciones de ventana)