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

Ver Requiere Lógica de interdependencia:¿Es posible sin MODEL?

Podría usar factorización de subconsultas recursivas (también conocido 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 .

Básicamente es caminar a través de los pasos manuales. El miembro ancla es su primer paso manual, configurando x y y ambos a cero para la primera fila. El miembro recursivo luego hace el cálculo que especificó. (No puede hacer referencia al nuevo x calculado valor al calcular el y de esa fila , entonces tienes que repetir eso como (tmp.n * 2) + r.y - 1 ). El rn es solo para mantener el orden de las filas por ID y facilitar la búsqueda de la siguiente fila, para que pueda buscar rn + 1 en lugar de buscar directamente el siguiente valor de ID más alto.

No hay una diferencia de rendimiento significativa con los datos de muestra, pero con mil filas añadidas, la cláusula del modelo tarda unos 5 segundos y la CTE recursiva tarda aproximadamente 1 segundo; con otro modelo de mil filas toma ~20 segundos y el CTE toma ~3 segundos; con otro modelo de mil filas tomó ~40 segundos y CTE tomó ~6 segundos; y con otras mil filas (4008 en total), el modelo tardó ~75 segundos y CTE tardó ~10 segundos. (Me aburrí esperando la versión del modelo con más filas que esa; lo maté después de cinco minutos con 10,000). Realmente no puedo decir cómo funcionará esto con sus datos reales, pero sobre esa base, probablemente valga la pena intentarlo.