Standaard RANGE / ROWS voor FIRST_VALUE (zoals voor elke andere analytische functie) is BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW .
Als u IGNORE NULLS . toevoegt , dan NULL waarden worden niet in aanmerking genomen bij het samenstellen van het bereik.
Het RANGE wordt BETWEEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCEPT FOR THE NULL ROWS (het is geen geldige OVER clausule).
Sinds je txt 's die NULL zijn hebben een hoge id 's, ze worden eerst geselecteerd en hun bereiken zijn leeg, omdat er geen niet-NULL zijn rijen ertussen en UNBOUNDED PRECEDING
U moet ofwel ORDER BY . wijzigen of RANGE clausule van uw vraag.
ORDER BY wijzigen zet de rijen met NULL id's aan het einde van het venster zodat een niet-NULL waarde (indien aanwezig) wordt altijd eerst geselecteerd en de RANGE begint gegarandeerd vanaf die waarde:
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 wijzigen herdefinieert bereik om alle niet-NULL op te nemen rijen in de partitie:
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