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