По подразбиране 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