The Last_value function returns value from the last row of the window. This allow a query to access value from multiple rows at once without doing self-join. In this function over clause with order by is mandatory to have an ordered result set.
Syntax
LAST_VALUE (Column Name) OVER
([partition_by_clause col1, col2,.] ORDER BY Col1,
Col2, .. FRAME_CLAUSE)
partition_by_clause divides the rows of the result sets
into partitions to which the function applies. It is an optional.
order_by_clause specify the order in which the operation
is performed. it is required.
frame_clause defines the subset (or frame) of the
partition being evaluated. Will see its in the example.
Let’s see the example
We have a table.
create table employee( id int identity(1,1) primary key, empid int, emp_name varchar(50), salary_withdraw decimal(18,10), withdraw_dt date ) |
Inserting some records in this
table.
insert into employee(empid,emp_name,salary_withdraw,withdraw_dt) values(1,'Bagesh',1002,'01-31-2024'); insert into employee(empid,emp_name,salary_withdraw,withdraw_dt) values(1,'Bagesh',1000,'02-29-2024'); insert into employee(empid,emp_name,salary_withdraw,withdraw_dt) values(1,'Bagesh',1020,'03-31-2024'); insert into employee(empid,emp_name,salary_withdraw,withdraw_dt) values(1,'Bagesh',1050,'04-30-2024'); insert into employee(empid,emp_name,salary_withdraw,withdraw_dt) values(1,'Bagesh',1030,'05-31-2024'); insert into employee(empid,emp_name,salary_withdraw,withdraw_dt) values(2,'Rajesh',2002,'02-29-2024'); insert into employee(empid,emp_name,salary_withdraw,withdraw_dt) values(2,'Rajesh',2009,'03-31-2024'); insert into employee(empid,emp_name,salary_withdraw,withdraw_dt) values(2,'Rajesh',2000,'04-30-2024'); insert into employee(empid,emp_name,salary_withdraw,withdraw_dt) values(2,'Rajesh',1999,'05-31-2024'); insert into employee(empid,emp_name,salary_withdraw,withdraw_dt) values(3,'Mohan',1012,'02-29-2024'); insert into employee(empid,emp_name,salary_withdraw,withdraw_dt) values(3,'Mohan',1052,'03-31-2024'); insert into employee(empid,emp_name,salary_withdraw,withdraw_dt) values(3,'Mohan',1082,'04-30-2024'); insert into employee(empid,emp_name,salary_withdraw,withdraw_dt) values(3,'Mohan',1002,'05-31-2024'); insert into employee(empid,emp_name,salary_withdraw,withdraw_dt) values(4,'Sohan',87,'02-29-2024'); insert into employee(empid,emp_name,salary_withdraw,withdraw_dt) values(4,'Sohan',77,'03-31-2024'); insert into employee(empid,emp_name,salary_withdraw,withdraw_dt) values(4,'Sohan',97,'04-30-2024'); insert into employee(empid,emp_name,salary_withdraw,withdraw_dt) values(4,'Sohan',67,'05-31-2024'); |
See the records in the table.
Basic use of LAST_VALUE Function
In the following example, LAST_VALUE function returns the
highest paid salary from the entire table, and if more than one employee having same salary then sort the
record based on empid in ascending order.
select empid,emp_name,salary_withdraw,withdraw_dt, LAST_VALUE(salary_withdraw) over(order by salary_withdraw rows between unbounded preceding and unbounded following) as highest_salary, LAST_VALUE(salary_withdraw) over(order by salary_withdraw desc rows between unbounded preceding and unbounded following) as lowest_salary from employee |
If we will not use frame_clause we will not get the correct value. See below
select empid,emp_name,salary_withdraw,withdraw_dt, LAST_VALUE(salary_withdraw) over(order by salary_withdraw ) as highest_salary, LAST_VALUE(salary_withdraw) over(order by salary_withdraw desc ) as
lowest_salary from employee |
So if we are using Last_value function we need
to use frame_clause.
Above statement using a
FRAME_CLAUSE,ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED
FOLLOWING Which tells the LAST_VALUE function that it’s frame starts at the first row
(UNBOUNDED PRECEDING ) and ends at the last row (UNBOUNDED
FOLLOWING) in the result set.
LAST_VALUE function with
PARTITION CLAUSE
In the following example, LAST_VALUE
function returns the highest salary employee in withdraw month.
select empid,emp_name,salary_withdraw,withdraw_dt, LAST_VALUE(salary_withdraw) over(partition by empid order by salary_withdraw rows between unbounded preceding and unbounded following) as highest_salary, LAST_VALUE(salary_withdraw) over(partition by empid order by salary_withdraw desc rows between unbounded preceding and unbounded following) as lowest_salary from employee |