Kümülatif sonuçların ve hareketli toplamların hesaplanması, SQL'de geleneksel olarak pencere fonksiyonları (örneğin, SUM() OVER(ORDER BY ...)) aracılığıyla gerçekleştirilmiştir; ancak veritabanı yönetim sisteminin erken veya basitleştirilmiş sürümlerinde yalnızca alt sorgular ve gruplama işlemleri mevcuttur. Tarihsel olarak veritabanı mimarları, pencere fonksiyonlarını destekleyen SQL:2003 standardının ortaya çıkmasından önce alternatif yollar aramışlardır.
Sorun: — Pencere fonksiyonları yoksa, her satır için açıkça önceki tüm değerlerin toplamının hesaplanması gerekir ki bu da yeterince büyük seçimlerde O(N^2) iç içe sorgulara yol açar; bunu aşmak için bazı hileler uygulanmadığı sürece.
Çözüm:
Genellikle, ilişkili alt sorgular veya değerlerin güncellenmesi için geçici tablolar kullanılır:
Örnek kod:
-- İlişkili sorguyla kümülatif toplam SELECT t1.id, t1.amount, ( SELECT SUM(t2.amount) FROM transactions t2 WHERE t2.id <= t1.id ) AS running_total FROM transactions t1 ORDER BY t1.id; -- Değeri manuel olarak güncelleyerek geçici tabloyla CREATE TEMPORARY TABLE temp_running (id INT, amount INT, running_total INT); -- Dış kodla (örneğin, pl/pgsql) satırları geçerek toplamı ekleme işlemi
Anahtar özellikler:
İlişkili alt sorguda ORDER BY garantili sıralama sağlar mı?
Hayır — alt sorgu sonuç üzerinde mutlaka etkili olmaz. Nihai seçim sıralaması her zaman ana sorguda dışarıdan belirlenir: sonuç yalnızca WHERE filtrelemesine bağlıdır.
Bu yaklaşımda kümülatif toplamın hesaplanmasını paralelleştirilebilir mi?
Hayır — ardışıklık çok önemlidir, özellikle de önceki satırlara bağlı hesaplamalarda, bu nedenle basit paralelleştirme normal SQL'de mümkün değildir.
Neden ilişkili alt sorgu çok sayıda satırda yavaş çalışır?
Her satır için önceki satırlar kümesi üzerinden toplam yeniden hesaplandığı için. Bu da O(N^2) işlemlere yol açar. 100 bin satırlık bir örnekte bu, dakikalar veya hatta saatler sürebilir.
Bir analist, tarih üzerinden ilişkili alt sorguyla günlük kümülatif gelir hesapladı, ancak tabloda periyodik olarak silinmiş id'ler (boşluklar) belirdi. Nihai toplam, tarih yerine id sırasından dolayı dalgalı düşüşler yaşadı.
Artılar:
Eksiler:
Bir mühendis, kümülatif toplamı ETL betiğine (Python/pandas) taşıdı, ardından nihai değerleri ayrı bir tabloya yükleyerek yalnızca yenilikleri senkronize etti. Nihai sonuçlar her zaman tarihe göre uyumlu, kod hızlı çalışıyor ve milyonlarca kayıtla işlem yapıyor.
Artılar:
Eksiler: