The LAST function is used to return the value of the last row within a window when the sort keys are the same. By using the LAST function, you can easily obtain specific values from a dataset for further data analysis and processing. This function is non-deterministic.
The return value type is the same as the expr parameter type.
-
Basic usage:
SELECT name, salary, LAST(salary) OVER (PARTITION BY salary ) as min_salary
FROM VALUES
('Eric', 1, 28000),
('Alex', 1, 32000),
('Felix', 2, 21000),
('Frank', 1, 30000),
('Tom', 2, 23000),
('Jane', 3, 29000),
('Jeff', 3, 35000),
('Paul', 2, 29000),
('Charles', 2, 23000),
('Charles F', 2, 23000),
('null',4,null),
('NotNull',4,23000)
AS tab(name, dep_no, salary);
+-----------+--------+------------+
| name | salary | min_salary |
+-----------+--------+------------+
| null | null | null |
| Eric | 28000 | 28000 |
| Jeff | 35000 | 35000 |
| Frank | 30000 | 30000 |
| Felix | 21000 | 21000 |
| Tom | 23000 | 23000 |
| Charles | 23000 | 23000 |
| Charles F | 23000 | 23000 |
| NotNull | 23000 | 23000 |
| Jane | 29000 | 29000 |
| Paul | 29000 | 29000 |
| Alex | 32000 | 32000 |
+-----------+--------+------------+
-
Ignore NULL Values:
In this example, we will ignore employees with NULL salaries.
SELECT name, salary, LAST(salary,true) OVER (PARTITION BY salary ) as min_salary
FROM VALUES
('Eric', 1, 28000),
('Alex', 1, 32000),
('Felix', 2, 21000),
('Frank', 1, 30000),
('Tom', 2, 23000),
('Jane', 3, 29000),
('Jeff', 3, 35000),
('Paul', 2, 29000),
('Charles', 2, 23000),
('Charles F', 2, 23000),
('null',4,null),
('NotNull',4,23000)
AS tab(name, dep_no, salary);
+-----------+--------+------------+
| name | salary | min_salary |
+-----------+--------+------------+
| null | null | null |
| Eric | 28000 | 28000 |
| Jeff | 35000 | 35000 |
| Frank | 30000 | 30000 |
| Felix | 21000 | 21000 |
| Tom | 23000 | 23000 |
| Charles | 23000 | 23000 |
| Charles F | 23000 | 23000 |
| NotNull | 23000 | 23000 |
| Jane | 29000 | 29000 |
| Paul | 29000 | 29000 |
| Alex | 32000 | 32000 |
+-----------+--------+------------+
-
Using in conjunction with ORDER BY:
SELECT name, salary, LAST(salary) OVER (PARTITION BY dep_no ORDER BY dep_no DESC) as min_salary
FROM VALUES
('Eric', 1, 28000),
('Alex', 1, 32000),
('Felix', 2, 21000),
('Frank', 1, 30000),
('Tom', 2, 23000),
('Jane', 3, 29000),
('Jeff', 3, 35000),
('Paul', 2, 29000),
('Charles', 2, 23000),
('Charles F', 2, 23000),
('null',4,null),
('NotNull',4,23000)
AS tab(name, dep_no, salary);
+-----------+--------+------------+
| name | salary | min_salary |
+-----------+--------+------------+
| Jane | 29000 | 35000 |
| Jeff | 35000 | 35000 |
| Eric | 28000 | 30000 |
| Alex | 32000 | 30000 |
| Frank | 30000 | 30000 |
| Felix | 21000 | 23000 |
| Tom | 23000 | 23000 |
| Paul | 29000 | 23000 |
| Charles | 23000 | 23000 |
| Charles F | 23000 | 23000 |
| null | null | 23000 |
| NotNull | 23000 | 23000 |
+-----------+--------+------------+
-
Using Window Functions:
When you need to apply the LAST function to the entire dataset, you can use the ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING clause.
SELECT name, salary, LAST(salary, true) OVER (ORDER BY salary ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) as global_min_salary
FROM VALUES
('Eric', 1, 28000),
('Alex', 1, 32000),
('Felix', 2, 21000),
('Frank', 1, 30000),
('Tom', 2, 23000),
('Jane', 3, 29000),
('Jeff', 3, 35000),
('Paul', 2, 29000),
('Charles', 2, 23000),
('Charles F', 2, 23000),
('null',4,null),
('NotNull',4,23000)
AS tab(name, dep_no, salary);
+-----------+--------+-------------------+
| name | salary | global_min_salary |
+-----------+--------+-------------------+
| null | null | 35000 |
| Felix | 21000 | 35000 |
| Tom | 23000 | 35000 |
| Charles | 23000 | 35000 |
| Charles F | 23000 | 35000 |
| NotNull | 23000 | 35000 |
| Eric | 28000 | 35000 |
| Jane | 29000 | 35000 |
| Paul | 29000 | 35000 |
| Frank | 30000 | 35000 |
| Alex | 32000 | 35000 |
| Jeff | 35000 | 35000 |
+-----------+--------+-------------------+