RANGE / ROWS
par défaut pour FIRST_VALUE
(comme pour toute autre fonction analytique) est BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
.
Si vous ajoutez IGNORE NULLS
, puis NULL
les valeurs ne sont pas prises en compte lors de la construction de la plage.
La RANGE
devient BETWEEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCEPT FOR THE NULL ROWS
(ce n'est pas un OVER
valide clause).
Depuis votre txt
's qui sont NULL
avoir un id
élevé 's, ils sont sélectionnés en premier et leurs plages sont vides, car il n'y a pas de non-NULL
lignes entre eux et UNBOUNDED PRECEDING
Vous devez modifier soit ORDER BY
ou RANGE
clause de votre requête.
Changer ORDER BY
met les lignes avec NULL
id est à la fin de la fenêtre de sorte qu'un non-NULL
la valeur (le cas échéant) sera toujours sélectionnée en premier, et la RANGE
commencera à coup sûr à partir de cette valeur :
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
Modification de RANGE
redéfinit la plage pour inclure tous les non-NULL
lignes dans la partition :
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