There is a table of the form:
CREATE SEQUENCE history_id_seq; CREATE TABLE history ( id INT8 DEFAULT nextval('history_id_seq') NOT NULL CONSTRAINT history_key PRIMARY KEY, objid TEXT NOT NULL, descr TEXT, value FLOAT4, time TIMESTAMP ); ALTER TABLE public.history OWNER TO postgres; CREATE INDEX idx_history_objid ON history USING BTREE (objid); CREATE INDEX idx_history_time ON history USING BTREE (time); INSERT INTO history ( objid, descr, value, time ) VALUES ( 'a', 'a_descr1', 0, '2016-06-23 00:00:00' ), ( 'b', 'b_descr1', 1, '2016-06-23 00:00:01' ), ( 'c', 'c_descr1', 2, '2016-06-23 00:00:02' ), ( 'a', 'a_descr2', 3, '2016-06-23 00:00:03' ); You need to select unique identifiers (objid) and recent descriptions (descr), since Descriptions may change over time.
objid | descr -------+---------- a | a_descr2 b | b_descr1 c | c_descr1 The required functionality gives me a query:
SELECT DISTINCT ON (objid) objid, descr, time FROM history ORDER BY objid, time DESC; But with millions of entries, this is a very long process. Simply select the unique objid quickly turned out with the help of the recursive function:
WITH RECURSIVE t(i) AS ( SELECT min(objid) FROM history UNION SELECT( SELECT objid FROM history WHERE objid > i ORDER BY objid LIMIT 1 ) FROM t WHERE i is not null ) SELECT * FROM t; but how to take descriptions is not clear. I would be grateful for any idea.
objidfrom the whole set? in percentage terms - ViktorovSELECT h1.objId, h1.descr FROM history AS h1 JOIN (SELECT objid, MAX(time) AS time FROM history GROUP BY objId) AS h2 ON h2.objId = h1.objId AND h2.time = h1.time ORDER BY h1.objId, h1.time DESCworks 3-4 times faster than your source. But still long, yes. - Yaant