I previously had this table:
CREATE TABLE traces_v0
( canvas_id UUID NOT NULL
, tlid BIGINT NOT NULL
, trace_id UUID NOT NULL
, timestamp TIMESTAMP WITH TIME ZONE NOT NULL
, PRIMARY KEY (canvas_id, tlid, trace_id)
);
which I'm trying to change into this table:
CREATE TABLE traces_v0
( canvas_id UUID NOT NULL
, root_tlid BIGINT NOT NULL
, trace_id UUID NOT NULL
, callgraph_tlids BIGINT[] NOT NULL
, timestamp TIMESTAMP WITH TIME ZONE NOT NULL
, PRIMARY KEY (canvas_id, root_tlid, trace_id)
);
Which is to say, where previously there was one row per (tlid, trace_id)
, there is now a single row with a trace_id
and an array of callgraph_tlids
.
I have a query which worked well on the old table:
SELECT tlid, trace_id
FROM (
SELECT
tlid, trace_id,
ROW_NUMBER() OVER (PARTITION BY tlid ORDER BY timestamp DESC) as row_num
FROM traces_v0
WHERE tlid = ANY(@tlids::bigint[])
AND canvas_id = @canvasID
) t
WHERE row_num <= 10
This fetches the last 10 (tlid, trace_id)
for each of tlids
(a bigint array) ordered by timestamp. This is exactly what I need and was very effective.
(fyi: the "at" (@tlids
) syntax is just a fancy way of writing $1
, supported by my postgres driver)
I'm struggling to port this to the new table layout. I came up with the following which works except that it doesn't limit to 10 per tlid
ordered by timestamp:
SELECT callgraph_tlids, trace_id
FROM traces_v0
WHERE @tlids && callgraph_tlids -- '&&' is the array overlap operator
AND canvas_id = @canvasID
ORDER BY timestamp DESC"
How can I do this query where I limit the results to 10 rows per tlid
, ordered by timestamp?
I'm using Postgres 9.6 if that matters.