CodingNeed.

1 · Reporting patterns and edge cases · 25 MIN

Compare each event with its predecessor

Compare each event with its predecessor

LAG reads a value from an earlier row in the same ordered partition without collapsing rows. Partitioning by category keeps one category from borrowing another’s history. ORDER BY id makes the predecessor deterministic. Arithmetic involving a NULL predecessor or current amount remains NULL; that is an unknown difference, not automatically zero. The first event has no predecessor and should be handled deliberately by the presentation layer.

Define the output row grain and ordering before choosing SQL operators.

Read the example

SELECT id, category, amount, amount - LAG(amount) OVER (PARTITION BY category ORDER BY id) FROM events ORDER BY id;
Check the expected output
[[1,"food",5,null],[2,"travel",3,null],[3,"food",7,2],[4,"travel",null,null],[5,"food",5,-2]]

Your challenge

Return id, category, amount and amount minus the previous amount within that category ordered by id. Keep NULL differences as NULL.

Solution cost: Aggregation scans input; window ordering can add O(n log n) sorting. Inspect the database plan. time · Grouping or window buffers depend on the plan and partition size. space

Common trap

Omitting a tie-breaker from window ordering can make predecessor selection ambiguous.

Further reading: SQLite window functions

Next lesson: Select one representative from each duplicate group

Essential cookies keep your account signed in. Optional analytics is not configured on this site. Your choice does not affect access to lessons.

Read the Privacy Policy. You can change this choice in the footer.