Aşağıdaki girdiye sahibim:
id | value
----+-------
1 | 136
2 | NULL
3 | 650
4 | NULL
5 | NULL
6 | NULL
7 | 954
8 | NULL
9 | 104
10 | NULL
Aşağıdaki sonucu bekliyorum:
id | value
----+-------
1 | 136
2 | 136
3 | 650
4 | 650
5 | 650
6 | 650
7 | 954
8 | 954
9 | 104
10 | 104
Önemsiz çözüm bir <
ilişki ile tablolara katılmak ve sonra MAX
a 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;
Ancak, bu kodun önemsiz bir şekilde yürütülmesi, dahili olarak giriş tablosundaki satır sayısının ( O (n ^ 2) ) karesini oluşturacaktır . T-sql'ın onu optimize etmesini bekledim - bir blok / kayıt düzeyinde, yapılacak iş çok kolay ve doğrusal, aslında bir for döngüsü ( O (n) ).
Ancak, denemelerimde, en son MS SQL 2016 bu sorguyu doğru şekilde optimize edemez ve bu sorguyu büyük bir giriş tablosu için yürütmeyi imkansız hale getirir.
Ayrıca, sorgu hızlı bir şekilde çalışmalı ve benzer şekilde kolay (ama çok farklı) imleç tabanlı bir çözümü olanaksız hale getirmelidir.
Bazı bellek destekli geçici tablo kullanmak iyi bir uzlaşma olabilir, ancak önemli ölçüde daha hızlı çalıştırılabilir olup olmadığını emin değilim, alt sorguları kullanarak benim örnek sorgu işe yaramadı.
Ayrıca t-sql belgelerinden bazı pencereleme işlevini kazmayı düşünüyorum, ne istediğimi yapmak için kandırılmış olabilir. Örneğin, kümülatif toplam çok benzer bir şey yapıyor, ancak en son null olmayan öğeyi vermek için kandıramadım ve önceki öğelerin toplamını değil.
İdeal çözüm, prosedür kodu veya geçici tablolar olmadan hızlı bir sorgu olacaktır. Alternatif olarak, geçici tablolar içeren bir çözüm de uygundur, ancak tabloyu prosedürel olarak yinelemek uygun değildir.