Sunday, August 4, 2013

Lag and Lead


Overview

SQL Server 2012 introduces following analytical functions

  • CUM_DIST & Percentile_DIST
  • FIRST_Value & Last_Value
  • LAG & LEAD
  • Percent_Count & Percent_Rank

Out of these, LAG & LEAD is very useful in almost all applications, where we need to find previous and next value based on a specific result-set and we need to do the self-join, LAG & LEAD completely gets rid off this self join and makes it very easy.

Syntax

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

Scenarios & Examples

  • Compare values between years

Let's say we have TotalSales per year for each product and now I want to compare with previous year sales and next year sales. look at the below query and we can know how easy it is to derive using these functions, otherwise we need to do self-joins and it is always painful.

SELECT ProductID, SaleYear, TotalSales, LAG(TotalSales,1,0) OVER (Order by SaleYear) PrevYearSales,
LEAD(TotalSales,1,0) OVER (Order by SaleYear) NextYearSales
FROM ProductSales
WHERE  ProductID = 2


ProductID
SaleYear
TotalSales
PrevYearSales
NextYearSales
2
2008
9000
0
96570
2
2009
96570
9000
67800
2
2010
67800
96570
78700
2
2011
78700
67800
90565
2
2012
90565
78700
0


0 is the default value, we will get 0 if function cannot derive anything. 

  • Use LAG, LEAD along with GROUP By

Let's say, we want to find out aggregated value of TotalSales per year and we want to compare with previous and next year, then here is the query

SELECT SaleYear, SUM(TotalSales) TotalSales, LAG(SUM(TotalSales),1,0) OVER (Order by SaleYear) PrevYearSales,
LEAD(SUM(TotalSales),1,0) OVER (Order by SaleYear) NextYearSales
FROM ProductSales
group by SaleYear

SaleYear
TotalSales
PrevYearSales
NextYearSales
2008
28000
0
232070
2009
232070
28000
142600
2010
142600
232070
136500
2011
136500
142600
174465
2012
174465
136500
0

  • Use LAG, LEAD within Partition

Let's say, we want to compare totalsales with previous and next year for all the products, then we can achieve this by integrating Partition by clause

SELECT ProductID, SaleYear, TotalSales, LAG(TotalSales,1,0) OVER (Partition By ProductID Order by SaleYear) PrevYearSales,
LEAD(TotalSales,1,0) OVER (Partition By ProductID Order by SaleYear) NextYearSales
FROM ProductSales

ProductID
SaleYear
TotalSales
PrevYearSales
NextYearSales
1
2008
10000
0
10400
1
2009
10400
10000
47000
1
2010
47000
10400
14500
1
2011
14500
47000
78000
1
2012
78000
14500
0
2
2008
9000
0
96570
2
2009
96570
9000
67800
2
2010
67800
96570
78700
2
2011
78700
67800
90565
2
2012
90565
78700
0
3
2008
8000
0
67800
3
2009
67800
8000
4500
3
2010
4500
67800
9000
3
2011
9000
4500
4500
3
2012
4500
9000
0
4
2008
1000
0
57300
4
2009
57300
1000
23300
4
2010
23300
57300
34300
4
2011
34300
23300
1400
4
2012
1400
34300
0

No comments:

Post a Comment