Reputation: 1845
I have a table where I need to find a value satisfying few conditions and if those conditions are satisfied I need to assign the same value to each of the columns
Table
ID Name Salary rownum
1 Jon 500 1
1 Jim 600 2
1 Jack 700 3
1 Bob 1000 4
2 Adam 500 1
2 Aron 600 2
2 James 900 3
2 Jay 1000 4
First condition is I need to have the same ID, then within the ID I need to compare the first row with the 2nd one if the difference is less than or equal to 100. I can only compare Rownum 1 with 2 and 2 with 3 and so on. After identifying if the condition is satisfied, I need to update the salary values to the value which exists for Rownum 1 until the point where the condition is satisfied keeping the names same.
Expected Output
Table
ID Name Salary rownum
1 Jon 500 1
1 Jim 500 2
1 Jack 500 3
1 Bob 1000 4
2 Adam 500 1
2 Aron 500 2
2 James 900 3
2 Jay 900 4
Jim had 600 as salary and difference with Jon's salary is <=100, and Jack had 700 difference with Jim's is <=100, as Jim is within Jon's salary and Jack is within Jim's salary these values are continuous, so we need Jon's value for these rows, while Bob is independent as it does not fall in the range. Same logic applies for ID = 2
Upvotes: 3
Views: 4476
Reputation: 17126
Your problem is not as simple as it appears as it is possible that preceding row may have greater value(say 800) compared to current row (say 750). It is also possible that there are more islands and gaps than simply one.
Below is my solution. Also see working demo
; with cte as
(
select *
, toUpdate= case
when
salary - lag( salary) over( partition by Id order by rownum asc) between 0 and 100
then
1
else
0
end
from t
)
update t5
set t5.salary=t4.newsalary
from t t5
join
(
select
t1.*,
rn=row_number () over( partition by t1.id, t1.rownum order by t3.rownum desc),
newsalary=t3.salary
from cte t1
outer apply
(
select *
from cte t2
where t2.id=t1.id
and t2.rownum<t1.rownum
and t2.toUpdate=0
) t3
)t4
on t4.rn=1 and t4.toUpdate=1 and t5.id=t4.id and t5.rownum=t4.rownum
select * from t
Upvotes: 2
Reputation: 3811
try this:
if
"left join self
+ where Salary + 100 * (jointable.rownum - rownum) = jointable.Salary
's data is not null" then update Salary
update T
set Salary = NewSalary
from (
select T2.*,T1.Salary NewSalary,(T2.rownum - T1.rownum) fd
from [Table] T1
left join [Table] T2 on T1.ID = T2.ID
and T1.rownum <> T2.rownum
and (T2.rownum - T1.rownum) > 0
and T1.[Salary] + 100 * (T2.rownum - T1.rownum) = T2.[Salary]
where T2.id is not null
) T ;
| ID | Name | Salary | rownum |
|----|-------|--------|--------|
| 1 | Jon | 500 | 1 |
| 1 | Jim | 500 | 2 |
| 1 | Jack | 500 | 3 |
| 1 | Bob | 1000 | 4 |
| 2 | Adam | 500 | 1 |
| 2 | Aron | 500 | 2 |
| 2 | James | 900 | 3 |
| 2 | Jay | 900 | 4 |
Upvotes: 3