Chạy tổng số đến hàng trước


14

Tôi cần một số trợ giúp với các chức năng cửa sổ. Tôi biết bạn có thể tính tổng trong một cửa sổ và tổng số đang chạy trong một cửa sổ. Nhưng có thể tính tổng chạy trước đó tức là tổng chạy không bao gồm hàng hiện tại không?

Tôi giả sử bạn sẽ cần phải sử dụng ROWhoặc RANGEđối số. Tôi biết có một CURRENT ROWtùy chọn nhưng tôi sẽ cần CURRENT ROW - 1, đó là cú pháp không hợp lệ. Kiến thức của tôi về ROWvà các RANGEđối số còn hạn chế nên mọi sự giúp đỡ đều được nhận một cách biết ơn.

Tôi biết rằng có nhiều giải pháp cho vấn đề này, nhưng tôi đang tìm cách hiểu ROW, các RANGElập luận và tôi cho rằng vấn đề có thể bị bẻ khóa với những vấn đề này. Tôi đã bao gồm một cách có thể để tính tổng chạy trước đó nhưng tôi tự hỏi liệu có cách nào tốt hơn không:

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

Câu trả lời:


22

Câu trả lời là sử dụng 1 PRECEDING, không phải CURRENT ROW -1. Vì vậy, trong truy vấn của bạn, sử dụng:

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

Cũng lưu ý rằng trên tính toán khác của bạn:

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

SQL-Server sử dụng mặc định * RANGE UNBOUNDED PRECEDING AND CURRENT ROW . Tôi nghĩ rằng có một sự khác biệt hiệu quả và ROWS UNBOUNDED PRECEDING AND CURRENT ROWsẽ được ưu tiên (sau khi thử nghiệm tất nhiên và nếu nó mang lại kết quả bạn muốn).

Nhiều chi tiết hơn bạn có thể tìm thấy trong bài viết trên blog của @Aaron Bertrand , bao gồm các bài kiểm tra hiệu suất: Cách tiếp cận tốt nhất để chạy tổng số - được cập nhật cho SQL Server 2012

* tất nhiên đây là phạm vi mặc định khi có ORDER BYmặt trong OVERmệnh đề - nếu không, không có ORDER BYmặc định là toàn bộ phân vùng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.