SQL OFFSET Functions – LAG, LEAD, FIRST_VALUE, LAST_VALUE

Last modified date:

OFFSET functions are relatively new to MS SQL Server. They are available since SQL Server 2012 version. These functions enable a user to “list” through rows of a table. To be precise, it makes you able to put hand on previous or next row while still at the current one.

These functions belong to a group of so-called Window functions. Aggregate functions and Ranking functions belong to the same group.

List of SQL Functions For The Access to Previous or Next Rows

  • LAG() – Finds the previous value in the table and returns it
  • LEAD() – Finds the next value in the table and returns it
  • FIRST_VALUE() – Finds and returns the lowest value according to the current row
  • LAST_VALUE() – Finds and returns the highest value according to the current row

Another way how to page through a table is OFFSET <nr of rows> FETCH NEXT <nr of rows> command. This command is used with clause ORDER BY. However, this is not a function and therefore it does not belong here.

Practical Example – LAG, LEAD, FIRST_VALUE, LAST_VALUE

We will create a table in which we will have 2015 Sales, month after month. We will then demonstrate offset functions on it. At the end we will try to write SQL script creating an index => month-on-month sales [%] using functions.

USE [tempdb];
CREATE TABLE [Example_Ranking] (
  [ID] INT IDENTITY(1,1)
  ,[Year] INT
  ,[Month] INT
  ,[Sales] NUMERIC
);

INSERT INTO [Example_Ranking] (
  [Year]
  ,[Month]
  ,[Sales]
)
VALUES
(2015, 1, 50)
,(2015, 2, 60)
,(2015, 3, 30)
,(2015, 4, 120)
,(2015, 5, 150)
,(2015, 6, 70)
,(2015, 7, 50)
,(2015, 8, 90)
,(2015, 9, 90)
,(2015, 10, 100)
,(2015, 11, 90)
,(2015, 12, 150)

The table looks like this:

offset functons example

Script:

SELECT
  [ID]
  ,[Year]
  ,[Month]
  ,[Sales]
  ,FIRST_VALUE([Sales]) OVER (ORDER BY [Year], [Month])    AS [First_Value]
  ,LAST_VALUE([Sales]) OVER (ORDER BY [Year], [Month])     AS [Last_Value]
  ,LAG([Sales]) OVER (ORDER BY [Year], [Month])            AS [Previous_Value]
  ,LEAD([Sales]) OVER (ORDER BY [Year], [Month])           AS [Next_value]
FROM [Example_Ranking];

Result:

lag, lead, first_value, last_value examples sql

How to Make an Index (month-on-month change) Using LAG() Function?

We can count a bunch of stuff using offset functions – for example, rate of growth between members of time line i.e. index. There is an example how to do it:

SELECT
  [ID]
  ,[Year]
  ,[Month]
  ,LAG([Sales]) OVER (ORDER BY [Year], [Month])         AS [Previous_Mesic]
  ,[Sales]                                              AS [Actual_mesic]
  ,CONVERT(NUMERIC(10,2),
      100*([Sales] - LAG([Sales]) OVER (ORDER BY [Year], [Month]))
        /
      LAG([Sales]) OVER (ORDER BY [Year], [Month]))     AS [Index %]
FROM [Example_Ranking];

Result:

calculate index in sql using lag offset function

My name is Jan Zedníček and I work as a BI Developer at Kentico Software in Brno. Mostly you can see me there working in the office, but I also work partly as a freelancer. I have been working as a freelancer for many companies for more than 5 years, but Kentico is the matter of my heart. I used to work as a financial controller at companies like Aero Vodochody or Sberbank and I also used to be a bond program manager in Unicapital Investment group. When I am not at work, I like playing volleyball, chess, doing a workout in the gym and I enjoy tasting of best quality rums. I am trying to summarize all my knowledge on this website not to forget them (because of the rum effect, you know =) and to put them forward to anyone. Don´t worry about asking for help or writing some comments.

Category: SQL Functions Useful SQL Scripts

About Ing. Jan Zedníček - BI Developer, Finance controller

My name is Jan Zedníček and I work as a BI Developer at Kentico Software in Brno. Mostly you can see me there working in the office, but I also work partly as a freelancer. I have been working as a freelancer for many companies for more than 5 years, but Kentico is the matter of my heart. I used to work as a financial controller at companies like Aero Vodochody or Sberbank and I also used to be a bond program manager in Unicapital Investment group. When I am not at work, I like playing volleyball, chess, doing a workout in the gym and I enjoy tasting of best quality rums. I am trying to summarize all my knowledge on this website not to forget them (because of the rum effect, you know =) and to put them forward to anyone. Don´t worry about asking for help or writing some comments.

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.