CREATE OR REPLACE FUNCTION updatescores() RETURNS void AS $BODY$DECLARE a float8; b float8; v float8; w float8; Al float8; Bl float8; Cl float8; C1 float8; C2 float8; C3 float8; c int4; d int4; e int4; x int4; y int4; z int4; i item%ROWTYPE; BEGIN C1 := 0.5; C2 := 0.3 * 5; C3 := 0.2 * 5; SELECT AVG(val) INTO v FROM Values; SELECT COUNT(id) INTO x FROM Values; IF x < 2 THEN x := 2; END IF; SELECT COUNT(id) INTO y FROM Guesses; SELECT AVG(val) INTO w FROM (SELECT val FROM Values ORDER BY val LIMIT (x + 1) % 2 + 1 OFFSET FLOOR(x / 2) - 1) as val; IF y < 2 THEN y := 2; END IF; SELECT SUM(views) INTO z FROM Items; IF z < 2 THEN z := 2; END IF; FOR i IN EXECUTE 'SELECT * FROM Items' LOOP SELECT AVG(val) INTO a FROM Values WHERE item_id = i.id; SELECT COUNT(id) INTO c FROM Values WHERE item_id = i.id; SELECT AVG(val) INTO b FROM (SELECT val FROM Values WHERE item_id = i.id ORDER BY val LIMIT (c + 1) % 2 + 1 OFFSET FLOOR(c / 2) - 1) as val; SELECT COUNT(id) INTO d FROM Guesses WHERE item_id = i.id; e := i.views; IF b IS NULL THEN b := 0; END IF; IF a IS NULL THEN a := 0; END IF; Al := LOG(x, (c + 1.0000000/x) ); IF Al < 0 THEN Al := 0; END IF; Bl := LOG(y, (d + 1.0000000/y) ); IF Bl < 0 THEN Bl := 0; END IF; Cl := LOG(z, (e + 1.0000000/z) ); IF Cl < 0 THEN Cl := 0; END IF; UPDATE Item SET score = C1 * ( (b * Al) + (v * (1 - Al) ) ) + ( (C2 * ( (a * Bl) + (w * (1 - Bl) ) ) ) / y) + ( (C3 * ( (a * Cl) + (w * (1 - Cl) ) ) ) / z) WHERE id = i.id; END LOOP; END;$BODY$ LANGUAGE 'plpgsql' VOLATILE;