По подразбиране RANGE / ROWS за FIRST_VALUE (както за всяка друга аналитична функция) е BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW .
Ако добавите IGNORE NULLS , след това NULL стойностите не се вземат предвид при изграждането на диапазона.
RANGE става BETWEEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCEPT FOR THE NULL ROWS (не е валиден OVER клауза).
Тъй като вашият txt които са NULL имат висок id те са избрани първи и диапазоните им са празни, тъй като няма не-NULL редове между тях и UNBOUNDED PRECEDING
Трябва да промените или ORDER BY или RANGE клауза на вашата заявка.
Промяна на ORDER BY поставя редовете с NULL id до края на прозореца, така че не-NULL стойност (ако има такава) винаги ще бъде избрана първа и RANGE гарантирано ще започне от тази стойност:
with t
as (
select 450 id, null txt , 3488 id_usr from dual union all
select 449 , null , 3488 from dual union all
select 79 , 'A' , 3488 from dual union all
select 78 , 'X' , 3488 from dual
)
select id
, txt
, id_usr
, first_value(txt) over (partition by id_usr order by NVL2(TXT, NULL, id) DESC) first_one
from t
Промяна на RANGE предефинира диапазон, за да включва всички не-NULL редове в дяла:
with t
as (
select 450 id, null txt , 3488 id_usr from dual union all
select 449 , null , 3488 from dual union all
select 79 , 'A' , 3488 from dual union all
select 78 , 'X' , 3488 from dual
)
select id
, txt
, id_usr
, first_value(txt IGNORE NULLS) over (partition by id_usr order by id DESC RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) first_one
from t