interview preparation
Difference Between FIRST_VALUE()
and LAST_VALUE()
in SQL
Both FIRST_VALUE()
and LAST_VALUE()
are analytics window functions that return specific values within a partition or window. The difference lies in which value they return: the first value or the last value based on the window’s ordering.
1. FIRST_VALUE()
:
- Purpose: Returns the first value in the window (or partition) based on the ordering of rows within that partition.
- Usage: It fetches the value from the first row in the window (partition) when sorted by a specified column in ascending or descending order.
Example: If we want to find the first sales amount for each salesperson, regardless of the current row’s position:
SELECT
SaleDate,
SalesAmount,
SalesRep,
FIRST_VALUE(SalesAmount) OVER (PARTITION BY SalesRep ORDER BY SaleDate) AS FirstSaleAmount
FROM Sales;
SaleDate | SalesAmount | SalesRep | FirstSaleAmount |
---|---|---|---|
2024-01-01 | 100 | Alice | 100 |
2024-01-03 | 150 | Alice | 100 |
2024-01-05 | 400 | Alice | 100 |
2024-01-02 | 200 | Bob | 200 |
2024-01-04 | 300 | Bob | 200 |
2024-01-06 | 500 | Bob | 200 |
In this example, FIRST_VALUE(SalesAmount)
always returns the first sales amount for each SalesRep
based on the SaleDate
.
2. LAST_VALUE()
:
- Purpose: Returns the last value in the window (or partition) based on the ordering of rows within that partition.
- Usage: It fetches the value from the last row in the window, which can be useful when calculating the most recent value in a sequence.
Example: If we want to find the last sales amount for each salesperson, regardless of the current row’s position:
SELECT
SaleDate,
SalesAmount,
SalesRep,
LAST_VALUE(SalesAmount) OVER (PARTITION BY SalesRep ORDER BY SaleDate ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS LastSaleAmount
FROM Sales;
SaleDate | SalesAmount | SalesRep | LastSaleAmount |
---|---|---|---|
2024-01-01 | 100 | Alice | 400 |
2024-01-03 | 150 | Alice | 400 |
2024-01-05 | 400 | Alice | 400 |
2024-01-02 | 200 | Bob | 500 |
2024-01-04 | 300 | Bob | 500 |
2024-01-06 | 500 | Bob | 500 |
Here, LAST_VALUE(SalesAmount)
returns the last sales amount for each SalesRep
, which is 400 for Alice and 500 for Bob.
Key Differences
Aspect | FIRST_VALUE() | LAST_VALUE() |
---|---|---|
Function | Returns the first value in the window or partition. | Returns the last value in the window or partition. |
Window Behavior | Based on the first row as per ORDER BY within the window. | Based on the last row as per ORDER BY within the window. |
Window Frame | Default window frame is from the first row to the current row. | Default window frame is from the current row to the last row. |
Common Use Case | Used when you need the first entry in a group (e.g., the first sales amount in a day or period). | Used when you need the last entry in a group (e.g., the most recent sales or transaction). |
Important Consideration
- For
LAST_VALUE()
to work correctly across the entire window, the window frame should be defined asROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
, otherwise, it might not return the true last value (it might just return the current row’s value).
Example with correct window frame for LAST_VALUE()
:
SELECT
SaleDate,
SalesAmount,
SalesRep,
LAST_VALUE(SalesAmount) OVER (PARTITION BY SalesRep ORDER BY SaleDate ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS LastSaleAmount
FROM Sales;