1. 程式人生 > >【FastReport教程】每個T-SQL程式設計師應該知道的視窗函式——第2部分(上)

【FastReport教程】每個T-SQL程式設計師應該知道的視窗函式——第2部分(上)

下載FastReport.Net最新版本

在本文的第二部分,我們將討論用於形成值的函式本身。視窗函式根據與當前行關聯的一組資料計算值,即,如果使用分割槽依據,則來自同一組的資料。用於 分組的常規聚合函式需要對行進行分組,從而從樣本中丟失必要的唯一資訊。因此,有必要使用兩個而不是單個請求,以便擁有所有必要的資料和按組的總和。視窗聚合函式允許在一個查詢 中實現相同的結果。視窗是一組用於計算函式的線。OVER指令將整個行集拆分為單獨的組 - 根據指定條件的視窗。 我們來談談視窗函式的型別。有三組目的地:

  • 聚合函式:SUM(),MAX(),MIN(),AVG()。COUNT()。這些函式返回通過算術計算獲得的值;

  • 排名函式:RANK(),DENSE_RANK(),ROW_NUMBER(),NTILE()。允許獲取視窗中的條目序列號;

  • 偏移功能:LAG(),LEAD(),FIRST_VALUE(),LAST_VALUE()。從另一個視窗行返回一個值。

為了演示函式的工作原理,我將使用一個簡單的表:

CREATE TABLE ForWindowFunc (ID INT, GroupId INT, Amount INT)
GO
 
INSERT INTO ForWindowFunc (ID, GroupId, Amount)
VALUES(1, 1, 100), (1, 1, 200), (1, 2, 150),
 (2, 1, 100), (2, 1, 300), (2, 2, 200), (2, 2, 50),
 (3, 1, 150), (3, 2, 200), (3, 2, 10);

聚合函式

SUM()

SUM()函式就像常規聚合函式一樣 - 它彙總了資料集中給定列的所有值。但是,由於OVER()指令,我們將資料集分解為視窗。根據ORDER BY子句中指定的順序在視窗內執行求和。讓我們看一個簡 單的例子 - 三組的總和。

SELECT ID,
 Amount,
 SUM(Amount) OVER (ORDER BY id) AS SUM FROM ForWindowFunc

FastReport

為方便起見,窗戶以不同顏色突出顯示。視窗中的所有值都具有相同的金額 - 視窗中所有金額的總和。

讓我們在選擇中新增另一列並更改OVER指令:

SELECT ID,
GroupId,
Amount,
SUM(Amount) OVER (Partition BY id ORDER BY id, GroupId) AS SUM
FROM ForWindowFunc

FastReport

如您所見,由於GroupId欄位,現在每個視窗都被分成組。現在每個小組都有自己的金額。 現在,讓我們在每個視窗中建立一個累積結果:

SELECT ID,
GroupId,
Amount,
SUM(Amount) OVER (Partition BY id ORDER BY id, GroupId, Amount) AS SUM
FROM ForWindowFunc

FastReport

我們不再需要GroupId欄位,因此我們將其從選擇中刪除。現在,對於視窗中的每一行,計算總計,即金額的當前值與之前所有金額的總和。

AVG()

此函式計算平均值。它可以與句子Partition by和Order by一起使用。

SELECT ID,
Amount,
AVG(Amount) OVER (Partition BY id ORDER BY id) AS AVG
FROM ForWindowFunc

FastReport

視窗中的每一行都有一個平均值Amount,它由公式計算:所有Amount /為行數的總和。 此函式的行為類似於SUM()。

MIN()

從函式的名稱可以清楚地看到它返回視窗中的最小值。

SELECT ID,
Amount,
MIN(Amount) OVER (Partition BY id ORDER BY id) AS MIN
FROM ForWindowFunc

FastReport

如您所見,在Min列中,視窗中顯示最小Amount值。

MAX()

MAX函式的工作方式與MIN相同,它只給出視窗中欄位的最大值:

SELECT ID,
Amount,
MAX(Amount) OVER (Partition BY id ORDER BY id) AS MAX
FROM ForWindowFunc

FastReport

一切都很清楚。在第一組中,最大金額為200,第二組為300,第三組為200。

count()

此函式返回視窗中的行數。

SELECT ID,
 Amount,
 COUNT(Amount) OVER (Partition BY id ORDER BY id) AS COUNT FROM ForWindowFunc

FastReport

使查詢更復雜一點,並新增GroupId欄位。

SELECT ID,
GroupId,
 Amount,
 COUNT(Amount) OVER (Partition BY id ORDER BY id, GroupId) AS COUNT
FROM ForWindowFunc

FastReport

在這種情況下,它更有趣。我們來看看第一個視窗。對於第一行和第二行,記錄數為2.但對於第三行,該值已經為3.我們設法累積了累計金額等組中的金額。 如果我們仍然需要每個組中的數字, 則需要將GroupId新增到Partition by子句中。

SELECT ID,
GroupId,
Amount,
COUNT(Amount) OVER (Partition BY id, GroupId) AS COUNT
FROM ForWindowFunc

FastReport