Я не уверен, что last_value будет делать то, что вы хотите.Было бы лучше использовать лаг:
select id,
coalesce(value, lag(value) OVER (order by id))
FROM test;
id | coalesce
----+----------
0 | A
1 | B
2 | C
3 | D
4 | E
5 | E
6 | F
(7 rows)
last_value вернет последнее значение текущего кадра.Поскольку вы разбили на части по идентификатору, в текущем кадре всегда будет только одно значение.lag вернет предыдущую строку (по умолчанию) в кадре, что, кажется, именно то, что вы хотите.
Чтобы немного расширить этот ответ, вы можете использовать row_number (), чтобы дать вам хорошее представление окадр, на который вы смотрите.Для вашего предложенного решения посмотрите на номера строк для каждой строки, когда вы разбиваете по id:
SELECT id, row_number() OVER (PARTITION BY id ORDER BY case WHEN value IS NULL THEN 0 ELSE 1 END ASC)
FROM test;
id | row_number
----+------------
0 | 1
1 | 1
2 | 1
3 | 1
4 | 1
5 | 1
6 | 1
(7 rows)
Каждая строка - это свой собственный фрейм, поэтому вы не сможете получить значения из других строк..
Если мы не разбиваем на части по идентификатору, но по-прежнему используем ваш порядок, вы можете понять, почему это не сработает для last_value:
SELECT id, row_number() OVER (ORDER BY case WHEN value IS NULL THEN 0 ELSE 1 END ASC, id)
FROM test;
id | row_number
----+------------
5 | 1
0 | 2
1 | 3
2 | 4
3 | 5
4 | 6
6 | 7
(7 rows)
В этом случае строкаэто был NULL, это первый.По умолчанию last_value будет включать строки до текущей строки, которая в данном случае является просто текущей строкой для идентификатора 5. Вы можете включить все строки в вашем фрейме:
SELECT id,
row_number() OVER (ORDER BY case WHEN value IS NULL THEN 0 ELSE 1 END ASC,
id ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING),
last_value(value) OVER (ORDER BY case WHEN value IS NULL THEN 0 ELSE 1 END ASC, id ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
FROM test;
id | row_number | last_value
----+------------+------------
5 | 1 | F
0 | 2 | F
1 | 3 | F
2 | 4 | F
3 | 5 | F
4 | 6 | F
6 | 7 | F
(7 rows)
Но теперь последняя строкаконец кадра и это явно не то, что вы хотите.Если вы ищете предыдущую строку, выберите lag ().