If you want a fixed number of "latest" entries, you need to use the window function row_number() (not rank()
). Although, if the eventid
happens to be unique (per itemid
), the only (slight) difference is performance. (Your question update confirms that.)
Also, you need a subquery for this, since WHERE
conditions are applied before window functions:
SELECT itemid, eventid, nodeid, eventseverity, eventtime, eventlogmsg
FROM (
SELECT itemid, eventid, nodeid, eventseverity, eventtime, eventlogmsg
,row_number() OVER (PARTITION BY itemid
ORDER BY eventid DESC NULLS LAST) AS rn
FROM events
WHERE nodeid IS NOT NULL
) sub
WHERE rn <= 20
ORDER BY 1, 2 DESC NULLS LAST;
The NULLS LAST
clause is only relevant if eventid
can be NULL, in which case this would sort rows with NULL values to the end. (Your question update rules that out, so the clause is not needed.)