從 SQL Server 2012 (11.x) 開始,不使用自聯(lián)接訪問同一結(jié)果集中前一行的數(shù)據(jù)。LAG 提供對位于當(dāng)前行之前的給定物理偏移量的行的訪問。在 SELECT 語句中使用此分析函數(shù)將當(dāng)前行中的值與前一行中的值進(jìn)行比較。
語法
LAG (scalar_expression [,offset] [,default]) OVER ( [ partition_by_clause ] order_by_clause )
scalar_expression
基于指定偏移量返回的值。它是返回單個(gè)(標(biāo)量)值的任何類型的表達(dá)式。scalar_expression不能是解析函數(shù)。
offset
從當(dāng)前行返回的行數(shù),從中獲取值。如果未指定,則默認(rèn)值為 1。offset可以是列、子查詢或其他計(jì)算結(jié)果為正整數(shù)或可以隱式轉(zhuǎn)換為bigint的表達(dá)式。offset不能是負(fù)值或解析函數(shù)。
default當(dāng)偏移量超出分區(qū)范圍
時(shí)返回的值。如果未指定默認(rèn)值,則返回 NULL。default可以是列、子查詢或其他表達(dá)式,但不能是分析函數(shù)。default必須與scalar_expression類型兼容。
OVER ( [ partition_by_clause ] order_by_clause )
partition_by_clause將 FROM 子句生成的結(jié)果集劃分為應(yīng)用該函數(shù)的分區(qū)。如果未指定,該函數(shù)將查詢結(jié)果集的所有行視為一個(gè)組。order_by_clause在應(yīng)用函數(shù)之前確定數(shù)據(jù)的順序。如果指定了partition_by_clause,它決定了分區(qū)中數(shù)據(jù)的順序。order_by_clause是必需的
返回類型
指定scalar_expression的數(shù)據(jù)類型。如果scalar_expression可以為空或默認(rèn)設(shè)置為 NULL,則返回 NULL。
例子
A. 比較年份之間的值
以下示例使用 LAG 函數(shù)返回特定員工與前幾年的銷售配額差異。請注意,由于第一行沒有可用的滯后值,因此返回默認(rèn)值零 (0)。
SELECT BusinessEntityID, YEAR(QuotaDate) AS SalesYear, SalesQuota AS CurrentQuota,
LAG(SalesQuota, 1,0) OVER (ORDER BY YEAR(QuotaDate)) AS PreviousQuota
FROM Sales.SalesPersonQuotaHistory
WHERE BusinessEntityID = 275 AND YEAR(QuotaDate) IN ('2005','2006');
結(jié)果:
A
B. 比較分區(qū)內(nèi)的值
以下示例使用 LAG 函數(shù)比較員工之間的年初至今銷售額。指定 PARTITION BY 子句以按銷售區(qū)域劃分結(jié)果集中的行。LAG 函數(shù)分別應(yīng)用于每個(gè)分區(qū),并為每個(gè)分區(qū)重新開始計(jì)算。OVER 子句中的 ORDER BY 子句對每個(gè)分區(qū)中的行進(jìn)行排序。SELECT 語句中的 ORDER BY 子句對整個(gè)結(jié)果集中的行進(jìn)行排序。請注意,由于每個(gè)分區(qū)的第一行沒有可用的滯后值,因此返回默認(rèn)值零 (0)。
SELECT TerritoryName, BusinessEntityID, SalesYTD,
LAG (SalesYTD, 1, 0) OVER (PARTITION BY TerritoryName ORDER BY SalesYTD DESC) AS PrevRepSales
FROM Sales.vSalesPerson
WHERE TerritoryName IN (N'Northwest', N'Canada')
ORDER BY TerritoryName;
結(jié)果:
B
C. 指定任意表達(dá)式
以下示例演示了在 LAG 函數(shù)語法中指定各種任意表達(dá)式。
CREATE TABLE T (a INT, b INT, c INT);
INSERT INTO T VALUES (1, 1, -3), (2, 2, 4), (3, 1, NULL), (4, 3, 1), (5, 2, NULL), (6, 1, 5);
SELECT b, c,
LAG(2*c, b*(SELECT MIN(b) FROM T), -c/2.0) OVER (ORDER BY a) AS i
FROM T;
結(jié)果:
C
D:比較季度之間的值
以下示例演示了 LAG 函數(shù)。該查詢使用 LAG 函數(shù)返回特定員工在前一個(gè)日歷季度的銷售配額差異。請注意,由于第一行沒有可用的滯后值,因此返回默認(rèn)值零 (0)。
SELECT CalendarYear, CalendarQuarter, SalesAmountQuota AS SalesQuota,
LAG(SalesAmountQuota,1,0) OVER (ORDER BY CalendarYear, CalendarQuarter) AS PrevQuota,
SalesAmountQuota - LAG(SalesAmountQuota,1,0) OVER (ORDER BY CalendarYear, CalendarQuarter) AS Diff
FROM dbo.FactSalesQuota
WHERE EmployeeKey = 272 AND CalendarYear IN (2001, 2002)
ORDER BY CalendarYear, CalendarQuarter;
結(jié)果
D



