Problems / Last Reading per Month / Editorial
This is the classic groupwise-maximum problem: the aggregate that defines the winner (MAX(reading_time)) is not the column you need to return (reading_value).
MAX(reading_time)
reading_value
sensor_id
date_trunc('month', reading_time)
readings
(sensor_id, reading_time)
date_trunc
CAST(... AS DATE)
month
GROUP BY collapses rows, so any non-aggregated column is lost — you cannot ask SQL for "the value *at* the max time" in a single grouped select. The two standard escapes are the max-then-join-back pattern used here and ROW_NUMBER ... ORDER BY reading_time DESC filtered to row 1. The join-back only works cleanly because the winning key is unique within each group (reading times are unique per sensor); when ties are possible, the window-function form with an explicit tiebreaker is the safer tool. Watch the data's traps: the last reading of a month is often *not* its largest value, and a reading at 00:05 on the 1st belongs to the new month, not the old one.
GROUP BY
00:05
Solve Last Reading per Month yourself →