Toplamı bir önceki satıra taşıma


14

Pencereleme işlevleriyle ilgili yardıma ihtiyacım var. Bir pencerede toplamı ve bir pencerede çalışan toplamı hesaplayabileceğinizi biliyorum. Fakat bir önceki koşu toplamını, yani mevcut satırı içermeyen koşu toplamını hesaplamak mümkün müdür?

ROWVeya RANGEargümanını kullanmanız gerektiğini varsayıyorum . Ben bir CURRENT ROWseçenek olduğunu biliyorum ama ihtiyacım var CURRENT ROW - 1, bu geçersiz sözdizimi. ROWVe RANGEargümanları hakkındaki bilgim sınırlıdır, bu nedenle herhangi bir yardım minnetle alınır.

Bu sorunun birçok çözüm olduğunu biliyorum ama anlamak arıyorum ROW, RANGEargümanları ve Sorun bunlarla kırık olabilir varsayalım. Önceki toplam toplamı hesaplamak için olası bir yol dahil ettim ama daha iyi bir yol olup olmadığını merak ediyorum:

USE AdventureWorks2012

SELECT s.SalesOrderID
    , s.SalesOrderDetailID
    , s.OrderQty
    , SUM(s.OrderQty) OVER (PARTITION BY  SalesOrderID) AS RunningTotal
    , SUM(s.OrderQty) OVER (PARTITION BY  SalesOrderID 
                         ORDER BY SalesOrderDetailID) - s.OrderQty AS PreviousRunningTotal
    -- Sudo code - I know this does not work
    --, SUM(s.OrderQty) OVER (PARTITION BY  SalesOrderID 
    --                   ORDER BY SalesOrderDetailID
    --                   ROWS BETWEEN UNBOUNDED PRECEDING 
    --                                   AND CURRENT ROW - 1) 
    -- AS  SudoCodePreviousRunningTotal
FROM Sales.SalesOrderDetail s
WHERE SalesOrderID IN (43670, 43669, 43667, 43663)
ORDER BY s.SalesOrderID
    , s.SalesOrderDetailID 
    , s.OrderQty

Yanıtlar:


22

Cevap kullanmaktır 1 PRECEDING, değil CURRENT ROW -1. Yani, sorgunuzda şunu kullanın:

    , SUM(s.OrderQty) OVER (PARTITION BY  SalesOrderID 
                            ORDER BY SalesOrderDetailID
                            ROWS BETWEEN UNBOUNDED PRECEDING 
                                     AND 1 PRECEDING) 
    AS  PreviousRunningTotal

Ayrıca diğer hesaplamalarınızda şunları unutmayın:

    , SUM(s.OrderQty) OVER (PARTITION BY  SalesOrderID
                            ORDER BY SalesOrderDetailID) ...

SQL-Server varsayılan * kullanır RANGE UNBOUNDED PRECEDING AND CURRENT ROW. Bir verimlilik farkı olduğunu ve ROWS UNBOUNDED PRECEDING AND CURRENT ROWtercih edileceğini düşünüyorum (elbette test ettikten sonra ve istediğiniz sonuçları veriyorsa).

Performans testleri de dahil olmak üzere @Aaron Bertrand'ın blog makalesinde bulabileceğiniz çok daha fazla ayrıntı : Toplamları çalıştırmak için en iyi yaklaşımlar - SQL Server 2012 için güncellendi

* bu, cümle ORDER BYiçinde an bulunduğunda varsayılan aralıktır OVER- aksi takdirde, ORDER BYvarsayılan olmadan tüm bölümdür.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.