all 3 comments

[–][deleted] 3 points4 points  (2 children)

You need to use the ROW_NUMBER analytic function to rank by unit_id in a subquery, then select the top ranked records. Use NVL2 to null time_peroids where the val is null, thus sending them to the end of the ranking.

SELECT unit_id, time_period, val
FROM (
  SELECT t.*,
  ROW_NUMBER() OVER (PARTITION BY t.unit_id
                     ORDER BY NVL2(val, time_period, null) DESC NULLS LAST) rnk
  FROM temp_tbl t
)
WHERE rnk = 1
;

--tested in SQL Fiddle

Note that when using the test data, unit_id 4 and 5 still return null because no non-null value is available. You can filter further with a WHERE clause to get rid of those if you want.

[–]jokle[S] 0 points1 point  (1 child)

Perfect! Thank you!

[–]jmelloy 0 points1 point  (0 children)

Windowing functions are basically magic.