Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Was ist falsch an dieser FIRST_VALUE-Abfrage?

Standard RANGE / ROWS für FIRST_VALUE (wie für jede andere analytische Funktion) ist BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW .

Wenn Sie IGNORE NULLS hinzufügen , dann NULL Werte werden bei der Bereichsbildung nicht berücksichtigt.

Der RANGE wird zu BETWEEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCEPT FOR THE NULL ROWS (es ist kein gültiger OVER Klausel).

Da Ihre txt , die NULL sind haben eine hohe id 's, sie werden zuerst ausgewählt und ihre Bereiche sind leer, da es keine Nicht-NULL gibt Zeilen dazwischen und UNBOUNDED PRECEDING

Sie sollten entweder ORDER BY ändern oder RANGE Klausel Ihrer Anfrage.

Ändern von ORDER BY setzt die Zeilen mit NULL id bis zum Ende des Fensters, sodass ein Nicht-NULL Wert (falls vorhanden) wird immer zuerst ausgewählt und der RANGE beginnt garantiert mit diesem Wert:

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

Ändern von RANGE definiert den Bereich neu, um alle Nicht-NULL einzuschließen Zeilen in der 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