I have the following table structures in a Postgres 9.1 database but the ideal solution should be DB agnostic if possible:
Table: users |id|username| |1 |one
Q1: FIRST_VALUE/LAST_VALUE
Q2: PARTITION BY (as Roman Pekar already suggested)
SEE FIDDLE HERE
SELECT
DISTINCT i.id AS id,
i.userid AS userid,
i.itemname AS itemname,
COALESCE(LEAD(i.id) OVER (ORDER BY i.created DESC)
,FIRST_VALUE(i.id) OVER (ORDER BY i.created DESC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)) AS nextitemid,
COALESCE(LAG(i.id) OVER (ORDER BY i.created DESC)
,LAST_VALUE(i.id) OVER (ORDER BY i.created DESC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)) AS previtemid,
COALESCE(LEAD(i.id) OVER (PARTITION BY i.userid ORDER BY i.created DESC)
,FIRST_VALUE(i.id) OVER (PARTITION BY i.userid ORDER BY i.created DESC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)) AS nextuseritemid,
COALESCE(LAG(i.id) OVER (PARTITION BY i.userid ORDER BY i.created DESC)
,LAST_VALUE(i.id) OVER (PARTITION BY i.userid ORDER BY i.created DESC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)) AS prevuseritemid,
i.created AS created
FROM items i
LEFT JOIN users u
ON i.userid = u.id
ORDER BY i.created DESC;