Saya memiliki input berikut:
id | value
----+-------
1 | 136
2 | NULL
3 | 650
4 | NULL
5 | NULL
6 | NULL
7 | 954
8 | NULL
9 | 104
10 | NULL
Saya mengharapkan hasil berikut:
id | value
----+-------
1 | 136
2 | 136
3 | 650
4 | 650
5 | 650
6 | 650
7 | 954
8 | 954
9 | 104
10 | 104
Solusi sepele akan bergabung dengan tabel dengan <
relasi, dan kemudian memilih MAX
nilai dalam GROUP BY
:
WITH tmp AS (
SELECT t2.id, MAX(t1.id) AS lastKnownId
FROM t t1, t t2
WHERE
t1.value IS NOT NULL
AND
t2.id >= t1.id
GROUP BY t2.id
)
SELECT
tmp.id, t.value
FROM t, tmp
WHERE t.id = tmp.lastKnownId;
Namun, eksekusi sepele dari kode ini akan membuat secara internal kuadrat dari jumlah baris dari tabel input ( O (n ^ 2) ). Saya berharap t-sql untuk mengoptimalkannya - pada level blok / catatan, tugas yang harus dilakukan sangat mudah dan linier, pada dasarnya a for loop ( O (n) ).
Namun, pada percobaan saya, MS SQL 2016 terbaru tidak dapat mengoptimalkan kueri ini dengan benar, membuat kueri ini tidak mungkin dijalankan untuk tabel input besar.
Selain itu, kueri harus berjalan cepat, membuat solusi berbasis kursor yang mudah (namun sangat berbeda) tidak layak digunakan.
Menggunakan beberapa tabel sementara yang didukung memori bisa menjadi kompromi yang baik, tetapi saya tidak yakin apakah itu dapat berjalan secara signifikan lebih cepat, menganggap bahwa kueri contoh saya menggunakan subquery tidak berfungsi.
Saya juga berpikir untuk menggali beberapa fungsi windowing dari t-sql docs, apa yang bisa diakali untuk melakukan apa yang saya inginkan. Sebagai contoh, jumlah kumulatif melakukan beberapa hal yang sangat mirip, tetapi saya tidak bisa menipu untuk memberikan elemen non-null terbaru, dan bukan jumlah elemen sebelumnya.
Solusi ideal adalah kueri cepat tanpa kode prosedural atau tabel sementara. Atau, solusi dengan tabel sementara tidak apa-apa, tetapi iterasi tabel secara prosedural tidak.
sumber