Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

A visualização requer lógica de interdependência:possível sem MODEL?


Você pode usar a fatoração de subconsulta recursiva (também conhecido como CTE recursivo):
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 .

É basicamente percorrer suas etapas manuais. O membro âncora é sua primeira etapa manual, configurando x e y ambos a zero para a primeira linha. O membro recursivo então faz o cálculo que você especificou. (Você não pode se referir ao x recém-calculado valor ao calcular o y dessa linha , então você tem que repetir isso como (tmp.n * 2) + r.y - 1 ). O rn é apenas manter a ordem das linhas por ID enquanto facilita a localização da próxima linha - para que você possa procurar por rn + 1 em vez de encontrar o próximo valor de ID mais alto diretamente.

Não há diferença significativa de desempenho com seus dados de amostra, mas com mil linhas adicionadas, a cláusula model leva cerca de 5 segundos e a CTE recursiva leva cerca de 1 segundo; com outras mil linhas, o modelo leva ~20 segundos e o CTE leva ~3 segundos; com outras mil linhas, o modelo levou ~40 segundos e o CTE levou ~6 segundos; e com outras mil linhas (portanto, 4.008 no total), o modelo levou ~75 segundos e o CTE levou ~10 segundos. (Fiquei entediado esperando a versão do modelo com mais linhas do que isso; matei depois de cinco minutos com 10.000). Eu realmente não posso dizer como isso funcionará com seus dados reais, mas com base nisso, provavelmente vale a pena tentar.