SQL Server窗口函數:ROWS與RANGE


幾乎每次我展示SQL Server里的窗口時,人們都非常有興趣知道,當你定義你的窗口(指定的一組行)時,ROWSRANGE選項之間的區別。因此在今天的文章里我想給你展示下這些選項的區別,對於你的分析計算意味着什么。

ROWS與RANGE之間的區別

當你用OVER()子句進行你的分析計算來打開你的窗口,你也可以在窗口里看到的,通過ROWSRANGE選項來限制你的行數。來看下面的T-SQL語句: 

 1 SELECT
 2     t.OrderYear,
 3     t.OrderMonth,
 4     t.TotalDue,
 5     SUM(t.TotalDue) OVER(ORDER BY t.OrderYear, t.OrderMonth ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS 'RunningTotal'
 6 FROM
 7 (
 8     SELECT
 9         YEAR(OrderDate) AS 'OrderYear',
10         MONTH(OrderDate) AS 'OrderMonth',
11         SalesPersonID,
12         TotalDue
13     FROM Sales.SalesOrderHeader 
14 ) AS t
15 WHERE
16     t.SalesPersonID = 274
17     AND t.OrderYear = 2005
18 GO

這個T-SQL語句用SUM()聚合函數進行匯總計算。窗口本身從第1行(UNBOUNDED PRECEDING)上至當前行(CURRENT ROW)。對於記錄級中的每1行,窗口變得越來越大,因此很容易進行匯總運算。下圖演示了這個概念。

從輸出你可以看到,結果是個自增長的匯總——運行合計匯總的結果。

現在假設你修改窗口為RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW,會發生什么:

 1 SELECT
 2     t.OrderYear,
 3     t.OrderMonth,
 4     t.TotalDue,
 5     SUM(t.TotalDue) OVER(ORDER BY t.OrderYear, t.OrderMonth RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS 'RunningTotal'
 6 FROM
 7 (
 8     SELECT
 9         YEAR(OrderDate) AS 'OrderYear',
10         MONTH(OrderDate) AS 'OrderMonth',
11         SalesPersonID,
12         TotalDue
13     FROM Sales.SalesOrderHeader 
14 ) AS t
15 WHERE
16     t.SalesPersonID = 274
17     AND t.OrderYear = 2005
18 GO

從下圖你可以看到,你得到了不同的結果,對於2005年11月的記錄顯示同樣的匯總。

我們來嘗試理解下為什么這里RANGE選項比ROWS選項給你不同的結果。使用ROWS選項你定義當前行的固定前后記錄。這里你看到的行取決於窗口的ORDER BY從句。你也可以說你在物理級別定義你的窗口。

當你使用RANGE選項事情就改變了。RANGE選項包含窗口里的所有行,和當前行有相同ORDER BY值。從剛才的圖片你可以看到,對於2005年11月的2條記錄你拿到同個匯總,因為這2行有同樣的ORDER BY值(2005年11月)。使用RANGE選項你在邏輯級別定義你的窗口。如果更多的行有同個ORDER BY值,當你使用ROWS選項你的窗口會包含更多的行。 

小結

在今天的文章里你看到了當你為你的分析計算定義窗口時,ROWS和RANGE選項之間的區別。使用ROWS選項你在物理級別定義在你窗口里有多少行。使用RANGE選項取決於ORDER BY值在窗口里有多少行被包含。因此當你使用RANGE選項時有性能上的巨大區別。在接下來的文章我會討論下這些副作用。

感謝關注!

參考文章:

https://www.sqlpassion.at/archive/2015/01/22/sql-server-windowing-functions-rows-vs-range/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM