 <p>Each pass of the loop is given the value of the record containing the corresponding row of the select result set. So <code>events</code> is not visible inside the loop. In instead use <code>d_cur.position</code> to refer to that column.</p> <p>BTW, as commented to your question, you should really use the <code>lag</code> window function and get rid of the messy loop.</p> <p>As a suggestion check this query:</p> <pre><code>select idx, asset_id, asset_name, previous_name, cont_name, position, evt_time from ( select rank() over (partition by e.asset_id order by e.event_time) as idx, st_distancesphere( e.position, lag(e.position, 1, e.position) over (order by e.event_time) ) &gt;= p_separation_distance as b, t.id as asset_id, t.name as asset_name, lag(c.name, 1) as previous_name, c.name as cont_name, e.position, e.event_time as evt_time from events e inner join assets tags on t.id = e.asset_id inner join assets c on c.id = e.container_asset_id where e.event_time &gt;= p_since_date and e.event_time &lt;= p_before_date ) s where b </code></pre>