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.