Wichtig: Ich benötige, dass dies mit SQL Server 2000 kompatibel ist.
Ich brauche eine kumulative Summe, aber basierend auf dem aktuellen Datum, eine Update-Abfrage wie die, die ich derzeit verwende, funktioniert, aber sie ist furchtbar langsam (hässlicher impliziter RBAR-Dreiecksjoin):
UPDATE #RPT
SET DailySumAccum =
(SELECT SUM(COALESCE(CTACTE2.Amount,0))
FROM #RPT_CTACTE CTACTE2
WHERE CTACTE2.IsAvailable = #RPT_CTACTE.IsAvailable
AND CTACTE2.CodCustomer = #RPT_CTACTE.CodCustomer
AND CTACTE2.ItemType = #RPT_CTACTE.ItemType
AND CTACTE2.CodItem = #RPT_CTACTE.CodItem
AND EsCtaCorrienteMon = -1
AND DATEDIFF(day, CTACTE2.OrderDate, #RPT_CTACTE.OrderDate) >= 0)
WHERE #RPT_CTACTE.EsSaldoAnterior = 0
AND EsCtaCorrienteMon = -1
Ich habe auch versucht, die Methode mit dem Cursor für kumulative Summen zu verwenden, aber ich kann das RBAR-Problem nicht lösen, die Datumsvergleiche sind immer noch da und es ist immer noch furchtbar langsam:
-- das ist im Cursor
IF (@EsCtaCorrienteMon = -1)
BEGIN
SELECT @NetoDiarioAcum = SUM(COALESCE(Amount,0))
FROM #RPT_CTACTE
WHERE IsAvailable = @IsAvailable
AND CodCustomer = @CodCustomer
AND ItemType = @ItemType
AND CodItem = @CodItem
AND EsCtaCorrienteMon = -1
AND DATEDIFF(day, OrderDate, @OrderDate) >= 0
END IF
Das Problem bei dieser kumulativen Summe ist der Datumsvergleich, der die Abfrage sehr langsam macht (nachdem der Code 10 Minuten lang ausgeführt wurde, dauert es nur 3 Sekunden, wenn ich das Update des Cursors auskommentiere), die Anzahl der Zeilen, die ich getestet habe, beträgt 28K, es scheint, dass die benötigte Zeit exponentiell ansteigt, wenn die Anzahl der Datensätze zunimmt, daher gehe ich davon aus, dass hier ein RBAR-Prozess stattfindet (was "Row-By-Agonizing-Row" bedeutet).
EDIT: Nach einigen Tests sieht es so aus, als ob das Datum nicht das einzige Problem ist, gibt es eine Möglichkeit, diese laufende Summe nur zu berechnen, indem man eine Variable innerhalb eines Cursors addiert oder so etwas?
EDIT2: Ich suche derzeit nach einer Möglichkeit, das zu tun, was das erste Update macht (eine laufende Summe basierend auf 4 Feldern und Datum), aber schneller, gestern war ich nah dran, die Logik manuell in einen Cursor einzufügen, aber der Cursor wurde zu groß und schwer zu pflegen, welche Laufende-Summen-Technik ist in diesem Fall am besten (schneller)? Und wie würden Sie diese Technik hier implementieren? Es handelt sich nicht um eine einfache laufende Summe, Schnitte sollten gemacht werden, wenn sich eines dieser Felder ändert. Das Feld EsSaldoAnterior
kann nur 0 oder -1 sein, das Update betrifft nur die äußere Tabelle, wenn dieses Feld 0 ist, aber die inneren laufenden Summen summieren sich auch, wenn dieses Feld -1 ist. EsSaldoAnterior
bedeutet so etwas wie "Sein Vorheriger Betrag" und es bedeutet, dass die laufenden Summen nicht bei null beginnen sollten, sie sollten diese Beträge zuerst summieren (wenn sie existieren), dies ist die Reihenfolge bei Verwendung von ORDER BY:
ORDER BY IsAvailable, CodCustomer, ItemType, CodItem, OrderDate, EsSaldoAnterior