sql >> Base de Datos >  >> RDS >> Oracle

¿Qué tiene de malo esta consulta FIRST_VALUE?

Predeterminado RANGE / ROWS para FIRST_VALUE (como para cualquier otra función analítica) es BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW .

Si agrega IGNORE NULLS , luego NULL los valores no se tienen en cuenta al construir el rango.

El RANGE se convierte en BETWEEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCEPT FOR THE NULL ROWS (no es un OVER válido cláusula).

Desde su txt que son NULL tener un alto id 's, se seleccionan primero y sus rangos están vacíos, ya que no hay valores que no sean NULL filas entre ellos y UNBOUNDED PRECEDING

Deberías cambiar ORDER BY o RANGE cláusula de su consulta.

Cambiar ORDER BY pone las filas con NULL id's hasta el final de la ventana para que un no NULL valor (si lo hay) siempre se seleccionará primero, y el RANGE comenzará con seguridad a partir de ese valor:

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

Cambiando RANGE redefine el rango para incluir todo lo que no sea NULL filas en la partición:

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