Oracle LAG Function

Summary: in this tutorial, you will learn how to access the row at a given offset prior to the current row using Oracle LAG() function.

Introduction to Oracle LAG() function #

Oracle LAG() is an analytic function that allows you to access the row at a given offset prior to the current row without using a self-join.

Here’s the basic syntax of the LAG() function:

LAG(expression [, offset ] [, default ])
OVER (
	[ query_partition_clause ] 
	order_by_clause
)Code language: SQL (Structured Query Language) (sql)

In this syntax:

expression #

is a scalar expression evaluated against the value of the row at a given offset prior to the current row.

offset #

is the number of rows that you want to backward from the current row. The default is 1.

default #

If the offset goes beyond the scope of the partition, the function returns the default. If you omit default, then the function returns NULL.

query_partition_clause #

The query_partition_clause clause divides rows into partitions to which the LAG() function is applied. By default, the function treats the whole result set as a single partition.

order_by_clause #

The order_by_clause clause specifies the order of the rows in each partition to which the LAG() function is applied.

Similar to the LEAD() function, the LAG() function is very useful for calculating the difference between the values of current and previous rows.

Oracle LAG() function examples #

We will reuse the salesman_performance view created in the LEAD() function tutorial for the demonstration.

If you have not created the salesman_performance view, you can use the following query:

CREATE OR REPLACE VIEW salesman_performance (salesman_id, YEAR, sales) AS
SELECT
  salesman_id,
  EXTRACT(
    YEAR
    FROM
      order_date
  ),
  SUM(quantity * unit_price)
FROM
  orders
  INNER JOIN order_items USING (order_id)
WHERE
  salesman_id IS NOT NULL
GROUP BY
  salesman_id,
  EXTRACT(
    YEAR
    FROM
      order_date
  );Code language: PHP (php)
SELECT
  salesman_id,
  YEAR,
  sales
FROM
  salesman_performance;Code language: SQL (Structured Query Language) (sql)

Using Oracle LAG() function over a result set example #

The following query uses the LAG() function to return sales and the previous year’s sales of the salesman id 62:

SELECT
  salesman_id,
  YEAR,
  sales,
  LAG (sales) OVER (
    ORDER BY
      YEAR
  ) py_sales
FROM
  salesman_performance
WHERE
  salesman_id = 62;Code language: SQL (Structured Query Language) (sql)

Here is the output:

Oracle LAG Function example

The first row returned NULL for the py_sales column because there was no previous row of the first row.

To calculate year over year sales performance of the salesman id 62, you can use a common table expression as shown in the following query:

WITH
  cte_sales (salesman_id, YEAR, sales, py_sales) AS (
    SELECT
      salesman_id,
      YEAR,
      sales,
      LAG (sales) OVER (
        ORDER BY
          YEAR
      ) py_sales
    FROM
      salesman_performance
    WHERE
      salesman_id = 62
  )
SELECT
  salesman_id,
  YEAR,
  sales,
  py_sales,
  CASE
    WHEN py_sales IS NULL THEN 'N/A'
    ELSE TO_CHAR ((sales - py_sales) * 100 / py_sales, '999999.99') || '%'
  END YoY
FROM
  cte_sales;Code language: SQL (Structured Query Language) (sql)

The following picture shows the result:

Oracle LAG Function YoY example

Using Oracle LAG() function over partitions example #

The following statement uses the LAG() function to return YoY sales performance of every salesman:

WITH
  cte_sales (salesman_id, YEAR, sales, py_sales) AS (
    SELECT
      salesman_id,
      YEAR,
      sales,
      LAG (sales) OVER (
        PARTITION BY
          salesman_id
        ORDER BY
          YEAR
      ) py_sales
    FROM
      salesman_performance
  )
SELECT
  salesman_id,
  YEAR,
  sales,
  py_sales,
  CASE
    WHEN py_sales IS NULL THEN 'N/A'
    ELSE TO_CHAR ((sales - py_sales) * 100 / py_sales, '999999.99') || '%'
  END YoY
FROM
  cte_sales;Code language: SQL (Structured Query Language) (sql)

The following picture shows the partial output:

Oracle LAG Function over partitions example

Summary #

  • Use the Oracle LAG() function to access data of the row at a given offset prior to the current row in the partition.
Was this tutorial helpful?