The window function first_value()
allows for a rather 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
. This way, non-null values come first. Order by ts
(timestamp column like you commented) next and you've got it in a single SELECT
.
This would be simpler if Postgres supported IGNORE NULLS
. The manual:
The SQL standard defines a RESPECT NULLS
or IGNORE NULLS
option for
lead
, lag
, first_value
, last_value
, and nth_value
. This is not
implemented in PostgreSQL: the behavior is always the same as the
standard's default, namely RESPECT NULLS
.
One of the few omissions with regard to standard SQL in this area.
We also cannot use a FILTER
clause. See:
The manual:
Only window functions that are aggregates accept a FILTER
clause.
db<>fiddle here
Old sqlfiddle