So far, Xorthax has been calculating totals and averages across rows. But now he wants to compare rows directly.
“What happened before this?” “What happens next?”
That’s where LAG() and LEAD() come in.
LAG() and LEAD() let you access values from other rows without joining the table to itself.
LAG(column) OVER (ORDER BY column)
LEAD(column) OVER (ORDER BY column)
LAG() → looks at a previous rowLEAD() → looks at a following row| OrderDate | Amount |
|---|---|
| 2024-01-01 | 100 |
| 2024-01-05 | 150 |
| 2024-01-10 | 200 |
SELECT OrderDate, Amount,
LAG(Amount) OVER (ORDER BY OrderDate) AS PrevAmount,
LEAD(Amount) OVER (ORDER BY OrderDate) AS NextAmount
FROM Orders;
Result:
| OrderDate | Amount | PrevAmount | NextAmount |
|---|---|---|---|
| 2024-01-01 | 100 | null | 150 |
| 2024-01-05 | 150 | 100 | 200 |
| 2024-01-10 | 200 | 150 | null |
Each row now includes values from the row before and after it.
ORDER BY OrderDate defines the sequence of rows.
ORDER BY is required for any LAG() or LEAD() statement.
LAG() looks one row backward in that sequence.
LEAD() looks one row forward.
For the first row, there is no previous value, so LAG() returns null.
For the last row, there is no next value, so LEAD() returns null.
These functions let you compare rows without writing joins or subqueries.
For each order, show the totalamount from the previous order based on orderdate.
| Column | Type |
|---|---|
| orderid | bigint |
| customerid | bigint |
| orderdate | timestamp without time zone |
| totalamount | double precision |
| status | text |
| Column |
|---|
| orderid |
| orderdate |
| totalamount |
| previous_amount |
Now that you can look at previous and next rows, you can start pulling specific values from a sequence.
Next, you’ll learn how to get the first value in a group.