Domyślny RANGE / ROWS
dla FIRST_VALUE
(jak w przypadku każdej innej funkcji analitycznej) jest BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
.
Jeśli dodasz IGNORE NULLS
, a następnie NULL
wartości nie są brane pod uwagę podczas budowania zakresu.
RANGE
staje się BETWEEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCEPT FOR THE NULL ROWS
(to nie jest prawidłowy OVER
klauzula).
Ponieważ twój txt
, które są NULL
mieć wysoki id
są wybierane jako pierwsze, a ich zakresy są puste, ponieważ nie ma wartości innych niż NULL
wierszy między nimi i UNBOUNDED PRECEDING
Powinieneś zmienić albo ORDER BY
lub RANGE
klauzula zapytania.
Zmiana ORDER BY
umieszcza wiersze z NULL
id znajduje się na końcu okna, więc nie NULL
wartość (jeśli istnieje) będzie zawsze wybierana jako pierwsza, a RANGE
na pewno zacznie się od tej wartości:
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
Zmiana RANGE
redefiniuje zakres, aby uwzględnić wszystkie inne niż NULL
wiersze w partycji:
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