The window function first_value() allows a fairly short and elegant solution:
SELECT first_value(a) OVER (ORDER BY a IS NULL, ts) AS a , first_value(b) OVER (ORDER BY b IS NULL, ts) AS b , first_value(c) OVER (ORDER BY c IS NULL, ts) AS c FROM t LIMIT 1;
a IS NULL evaluates to TRUE or FALSE . FALSE sorts before TRUE . So nonzero values come first. This is followed by ts by ts (timestamp column, as you commented), and you will get it in one SELECT .
This would be easier if Postgres supported IGNORE NULLS . Leadership:
The SQL standard defines RESPECT NULLS or IGNORE NULLS options for lead , lag , first_value , last_value and nth_value . This is not implemented in PostgreSQL: the behavior always matches the standard default value, namely RESPECT NULLS .
One of the few omissions regarding standard SQL in this area.
db <> fiddle here
SQL Fiddle
Erwin brandstetter
source share