Oracle
 sql >> Database >  >> RDS >> Oracle

Visualizza richiede logica di interdipendenza:possibile senza MODEL?

Potresti usare fattorizzazione ricorsiva di sottoquery (noto anche come CTE ricorsivo):

with tmp as (
  select t.*,
    row_number() over (order by t.id) as rn
  from t
),
r (id, n, x, y, rn) as (
  select id, n, 0, 0, rn
  from tmp
  where rn = 1
  union all
  select tmp.id, tmp.n, r.y - 1, (tmp.n * 2) + r.y - 1, tmp.rn
  from r
  join tmp on tmp.rn = r.rn + 1
)
select id, n, x, y
from r
order by rn;

        ID          N          X          Y
---------- ---------- ---------- ----------
         2          0          0          0 
         3          1         -1          1 
         5          1          0          2 
         7          2          1          5 
        11          3          4         10 
        13          5          9         19 
        17          8         18         34 
        19         13         33         59 

SQL Fiddle .

Fondamentalmente sta seguendo i tuoi passaggi manuali. Il membro anchor è il tuo primo passaggio manuale, l'impostazione di x e y entrambi a zero per la prima riga. Il membro ricorsivo esegue quindi il calcolo specificato. (Non puoi fare riferimento al nuovo x calcolato valore durante il calcolo di y di quella riga , quindi devi ripeterlo come (tmp.n * 2) + r.y - 1 ). Il rn serve solo a mantenere gli ordini delle righe per ID mentre è più facile trovare la riga successiva, così puoi cercare rn + 1 invece di trovare direttamente il valore ID successivo più alto.

Non c'è alcuna differenza di prestazioni significativa con i dati di esempio, ma con un migliaio di righe aggiunte la clausola del modello richiede circa 5 secondi e il CTE ricorsivo richiede circa 1 secondo; con altre mille righe il modello impiega ~20 secondi e il CTE impiega ~3 secondi; con altre mille righe il modello ha impiegato circa 40 secondi e il CTE ha impiegato circa 6 secondi; e con altre mille righe (quindi 4.008 in totale) il modello ha impiegato circa 75 secondi e il CTE ha impiegato circa 10 secondi. (Mi sono annoiato ad aspettare la versione del modello con più righe di quella; l'ho ucciso dopo cinque minuti con 10.000). Non posso davvero dire come funzionerà con i tuoi dati reali, ma su questa base, probabilmente vale la pena provare.