Oracle
 sql >> Base de données >  >> RDS >> Oracle

Voir Nécessite une logique d'interdépendance :Possible sans MODÈLE ?

Vous pouvez utiliser la la factorisation récursive des sous-requêtes (également appelé CTE récursif) :

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 .

Il s'agit essentiellement de suivre vos étapes manuelles. Le membre d'ancrage est votre première étape manuelle, la définition de x et y les deux à zéro pour la première ligne. Le membre récursif effectue ensuite le calcul que vous avez spécifié. (Vous ne pouvez pas vous référer au nouveau x calculé valeur lors du calcul de y de cette ligne , vous devez donc répéter cela sous la forme (tmp.n * 2) + r.y - 1 ). Le rn est juste de conserver les ordres de lignes par ID tout en facilitant la recherche de la ligne suivante - vous pouvez donc rechercher rn + 1 au lieu de trouver directement la prochaine valeur d'ID la plus élevée.

Il n'y a pas de différence de performances significative avec vos exemples de données, mais avec un millier de lignes ajoutées, la clause de modèle prend environ 5 secondes et le CTE récursif prend environ 1 seconde. avec un autre modèle de mille lignes prend environ 20 secondes et le CTE prend environ 3 secondes ; avec un autre millier de lignes, le modèle a pris environ 40 secondes et le CTE a pris environ 6 secondes ; et avec un autre millier de lignes (donc 4 008 au total), le modèle a pris environ 75 secondes et le CTE a pris environ 10 secondes. (Je me suis ennuyé en attendant la version modèle avec plus de lignes que cela ; je l'ai tué après cinq minutes avec 10 000). Je ne peux pas vraiment dire comment cela fonctionnera avec vos données réelles, mais sur cette base, cela vaut probablement la peine d'essayer.