Share via


LAG (Transact-SQL)

不使用 SQL Server 2012 的自我聯結,而從相同結果集的前一個資料列存取資料。 LAG 在跟隨目前資料列的已指定實體位移中,提供存取資料列。 在 SELECT 陳述式中使用這個分析函數,比較目前資料列中的值與前一個資料列中的值。

主題連結圖示 Transact-SQL 語法慣例 (Transact-SQL)

語法

LAG (scalar_expression [,offset] [,default])
    OVER ( [ partition_by_clause ] order_by_clause )

引數

  • scalar_expression
    根據指定的位移傳回數值。 傳回單一 (純量) 值的任一類型運算式。 scalar_expression 不能是分析函數。

  • offset
    從取得數值的目前資料列傳回資料列的數目。 若未加以指定,預設為 1。 offset 可以是資料行、子查詢或其他運算式,能算出正整數或可以明確地轉換為 bigint。 offset 不能是負值或分析函數。

  • default
    當 scalar_expression 在 offset 時,傳回的數值為 NULL。 如果未指定預設值,會傳回 NULL。 default 可以是資料行、子查詢或其他運算式,但不能是分析函數。 default 的類型必須與 scalar_expression 相容。

  • OVER ( [ partition_by_clause ] order_by_clause**)**
    partition_by_clause 將 FROM 子句產生的結果集分割到函數所套用的資料分割中。 如未指定,此函數會將查詢結果集的所有資料列視為單一群組。 在套用函數之前,order_by_clause 可指定資料順序。 當指定 partition_by_clause 時,即決定資料分割中的資料次序。 order_by_clause 是必要項目。 如需詳細資訊,請參閱<OVER 子句 (Transact-SQL)>。

傳回類型

已指定的 scalar_expression 資料類型。 如果 scalar_expression 是 nullable 或 default 設為 NULL,會傳回 NULL。

範例

A.比較不同年份的值

下列範例使用 LAG 函數傳回特定員工於前幾年之間的銷售配額差異。 請注意,由於第一列沒有可用的 lag 值,所以會傳回預設值零 (0)。

USE AdventureWorks2012;
GO
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');

以下為結果集:

BusinessEntityID SalesYear   CurrentQuota          PreviousQuota
---------------- ----------- --------------------- ---------------------
275              2005        367000.00             0.00
275              2005        556000.00             367000.00
275              2006        502000.00             556000.00
275              2006        550000.00             502000.00
275              2006        1429000.00            550000.00
275              2006        1324000.00            1429000.00

B.比較資料分割中的值

下列範例使用 LAG 函數比較年初至今各員工的銷售額。 指定 PARTITION BY 子句可依照銷售領域分割結果集中的資料列。 LAG 函數會分別套用至每個資料分割,並會針對每個資料分割重新開始計算。 OVER 子句中的 ORDER BY 子句會將每個資料分割中的資料列排序。 SELECT 陳述式中的 ORDER BY 子句會排序整個結果集的資料列。 請注意,由於每個資料分割的第一列沒有可用的 lag 值,所以會傳回預設值零 (0)。

USE AdventureWorks2012;
GO
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;

以下為結果集:

TerritoryName            BusinessEntityID SalesYTD              PrevRepSales
-----------------------  ---------------- --------------------- ---------------------
Canada                   282              2604540.7172          0.00
Canada                   278              1453719.4653          2604540.7172
Northwest                284              1576562.1966          0.00
Northwest                283              1573012.9383          1576562.1966
Northwest                280              1352577.1325          1573012.9383

C.指定任意的運算式

下列範例將示範如何在 LAG 函數語法中指定多種任意的運算式。

CREATE TABLE T (a int, b int, c int); 
GO
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;

以下為結果集:

b           c           i
----------- ----------- -----------
1           -3          1
2           4           -2
1           NULL        8
3           1           -6
2           NULL        NULL
1           5           NULL

請參閱

參考

LEAD (Transact-SQL)