My version uses a join of the MyObjects table with a subset of itself created by a subquery and containing only the latter for each object:
SELECT O.id,generation,value FROM MyObjects O, (SELECT id,max(generation) AS max_generation FROM MyObjects WHERE generation <= $GENERATION_ID GROUP BY id) AS TheMax WHERE TheMax.max_generation = generation AND O.deleted is False ORDER BY generation DESC;
In the above query, GENERATION_ID is tightly bound. The way parametrize is to write a function:
CREATE OR REPLACE FUNCTION generation_objects(INTEGER) RETURNS SETOF MyObjects AS 'SELECT O.id,generation,value,deleted FROM MyObjects O, (SELECT id,max(generation) AS max_generation FROM MyObjects WHERE generation <= $1 GROUP BY id) AS TheMax WHERE TheMax.max_generation = generation AND O.deleted is False;' LANGUAGE SQL;
Now it works. Using this table:
> SELECT * FROM MyObjects; id | generation | value | deleted ----+------------+-------+--------- 1 | 1 | 99 | f 2 | 2 | 88 | f 1 | 3 | 77 | f 2 | 4 | 88 | t 3 | 5 | 33 | f 4 | 6 | 22 | f 3 | 7 | 11 | f 2 | 8 | 11 | f
I get:
> SELECT * FROM generation_objects(1) ORDER by generation DESC; id | generation | value | deleted ----+------------+-------+--------- 1 | 1 | 99 | f > SELECT * FROM generation_objects(2) ORDER by generation DESC; id | generation | value | deleted ----+------------+-------+--------- 2 | 2 | 88 | f 1 | 1 | 99 | f > SELECT * FROM generation_objects(3) ORDER by generation DESC; id | generation | value | deleted ----+------------+-------+--------- 1 | 3 | 77 | f 2 | 2 | 88 | f
And then, in the next generation, object 2 is deleted:
> SELECT * FROM generation_objects(4) ORDER by generation DESC; id | generation | value | deleted ----+------------+-------+--------- 1 | 3 | 77 | f
source share