Anda dapat menggunakan pemfaktoran subkueri rekursif (juga dikenal sebagai CTE rekursif):
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
Ini pada dasarnya berjalan melalui langkah-langkah manual Anda. Anggota jangkar adalah langkah manual pertama Anda, mengatur x
dan y
keduanya menjadi nol untuk baris pertama. Anggota rekursif kemudian melakukan perhitungan yang Anda tentukan. (Anda tidak dapat merujuk ke x
yang dihitung baru nilai saat menghitung y
row baris itu , jadi Anda harus mengulanginya sebagai (tmp.n * 2) + r.y - 1
). rn
hanya untuk menyimpan urutan baris menurut ID sambil mempermudah menemukan baris berikutnya - sehingga Anda dapat mencari rn + 1
daripada langsung mencari nilai ID tertinggi berikutnya.
Tidak ada perbedaan kinerja yang signifikan dengan data sampel Anda, tetapi dengan seribu baris ditambahkan, klausa model membutuhkan waktu sekitar 5 detik dan CTE rekursif membutuhkan waktu sekitar 1 detik; dengan model seribu baris lainnya membutuhkan ~20 detik dan CTE membutuhkan ~3 detik; dengan model seribu baris lainnya membutuhkan waktu ~40 detik dan CTE membutuhkan waktu ~6 detik; dan dengan seribu baris lagi (jadi total 4.008) model membutuhkan ~75 detik dan CTE membutuhkan ~10 detik. (Saya bosan menunggu versi model dengan lebih banyak baris dari itu; membunuhnya setelah lima menit dengan 10.000). Saya tidak bisa mengatakan bagaimana kinerjanya dengan data asli Anda, tetapi atas dasar itu, mungkin patut dicoba.