Standard RANGE / ROWS för FIRST_VALUE (som för alla andra analytiska funktioner) är BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW .
Om du lägger till IGNORE NULLS , sedan NULL värden tas inte med i beräkningen när intervallet byggs upp.
RANGE blir BETWEEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCEPT FOR THE NULL ROWS (det är inte en giltig OVER klausul).
Eftersom din txt s som är NULL har högt id s, väljs de först och deras intervall är tomma, eftersom det inte finns någon icke-NULL rader mellan dem och UNBOUNDED PRECEDING
Du bör ändra antingen ORDER BY eller RANGE klausul i din fråga.
Ändra ORDER BY sätter raderna med NULL id är till slutet av fönstret så att en icke-NULL värde (om något) kommer alltid att väljas först, och RANGE kommer garanterat att börja från det värdet:
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
Ändra RANGE omdefinierar intervallet så att det inkluderar alla icke-NULL rader i partitionen:
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