Oracle SQL 游标增加工资直到达到最大金额
Oracle SQL Cursor to increase salaries until the max amount is reached
对于这个问题,我需要将 employees.salary 增加 20%,从最低工资开始(升序)直到用完 $100,000。我很难找到关于如何保存更新后的剩余金额直到 100,000 美元用完的解决方案。这是我到目前为止所拥有的。谢谢
declare
cursor mancur is
select salary from employees order by salary asc;
tempcur mancur%ROWTYPE;
profits number := 100000;
tempsalary employees.salary%type;
tempinc number(8,2);
begin
open mancur;
loop
fetch mancur into tempcur;
tempinc := tempcur.salary * 1.20;
tempsalary := profits - tempcur.salary;
dbms_output.put_line(tempcur.salary || ' increased by 20% ' || tempinc || ', Bonus amount left ' || tempsalary);
exit when mancur%notfound; --when 100,000 has been used
--update employees set salary = salary * 1.20 where employee_id = tempcur.employee_id;
end loop;
close mancur;
end;
/
begin
open mancur;
loop
fetch mancur into tempcur;
tempinc := tempcur.salary * 1.20;
profits := profits - (tempinc-tempcur.salary); -- You have to keep subtracting the increment amount to find if bonus is exhausted or not
if profits <=0 Then --When all your funds are exhausted
Exit
End if
dbms_output.put_line(tempcur.salary || ' increased by 20% ' || tempinc || ', Bonus amount left ' || profits);
exit when mancur%notfound; --when 100,000 has been used
--update employees set salary = salary * 1.20 where employee_id =
tempcur.employee_id;
end loop;
close mancur;
end;
/
declare
profits number := 100000;
tempinc number(8,2);
begin
for hike_loop in (select employee_id,salary from employees order by salary asc) loop
if profits <= 0 then
break;
end if;
tempinc := hike_loop.salary * 0.20;
if (tempinc <= profits) then
update employees set salary = salary * 1.20 where employee_id = hike_loop.employee_id;
profits := profits - tempinc;
else
break;
end if;
end loop;
end;
/
只是为了好玩:这是应该如何简单地完成 SQL。这个任务不需要函数或过程,除非它是 PL/SQL class 中的作业。即使这样,相同的 MERGE
语句也应该是 PL/SQL 代码中的 运行,这样处理是在设置级别完成的,而不是逐行完成的。
这也解决了 "small remaining amount" 与目前发布的解决方案不同的问题。如果不足以将 "last" 的薪水增加 20%,则可以增加,但最多增加 100,000 美元。而如果两个或两个以上的员工工资相同"the first to be left out",则"remaining amount"平分给这些员工。
merge into employees e
using ( select employee_id,
sum (salary) over (order by salary) as sum_salary,
count(salary) over (partition by salary) as cnt
from employees
) x
on ( e.employee_id = x.employee_id )
when matched then update
set salary = 1.2 * salary + case when sum_salary <= 100000 / 0.2 then 0
else (100000 - 0.2 * sum_salary) / cnt end
where sum_salary - cnt * salary <= 100000 / 0.2
;
对于这个问题,我需要将 employees.salary 增加 20%,从最低工资开始(升序)直到用完 $100,000。我很难找到关于如何保存更新后的剩余金额直到 100,000 美元用完的解决方案。这是我到目前为止所拥有的。谢谢
declare
cursor mancur is
select salary from employees order by salary asc;
tempcur mancur%ROWTYPE;
profits number := 100000;
tempsalary employees.salary%type;
tempinc number(8,2);
begin
open mancur;
loop
fetch mancur into tempcur;
tempinc := tempcur.salary * 1.20;
tempsalary := profits - tempcur.salary;
dbms_output.put_line(tempcur.salary || ' increased by 20% ' || tempinc || ', Bonus amount left ' || tempsalary);
exit when mancur%notfound; --when 100,000 has been used
--update employees set salary = salary * 1.20 where employee_id = tempcur.employee_id;
end loop;
close mancur;
end;
/
begin
open mancur;
loop
fetch mancur into tempcur;
tempinc := tempcur.salary * 1.20;
profits := profits - (tempinc-tempcur.salary); -- You have to keep subtracting the increment amount to find if bonus is exhausted or not
if profits <=0 Then --When all your funds are exhausted
Exit
End if
dbms_output.put_line(tempcur.salary || ' increased by 20% ' || tempinc || ', Bonus amount left ' || profits);
exit when mancur%notfound; --when 100,000 has been used
--update employees set salary = salary * 1.20 where employee_id =
tempcur.employee_id;
end loop;
close mancur;
end;
/
declare
profits number := 100000;
tempinc number(8,2);
begin
for hike_loop in (select employee_id,salary from employees order by salary asc) loop
if profits <= 0 then
break;
end if;
tempinc := hike_loop.salary * 0.20;
if (tempinc <= profits) then
update employees set salary = salary * 1.20 where employee_id = hike_loop.employee_id;
profits := profits - tempinc;
else
break;
end if;
end loop;
end;
/
只是为了好玩:这是应该如何简单地完成 SQL。这个任务不需要函数或过程,除非它是 PL/SQL class 中的作业。即使这样,相同的 MERGE
语句也应该是 PL/SQL 代码中的 运行,这样处理是在设置级别完成的,而不是逐行完成的。
这也解决了 "small remaining amount" 与目前发布的解决方案不同的问题。如果不足以将 "last" 的薪水增加 20%,则可以增加,但最多增加 100,000 美元。而如果两个或两个以上的员工工资相同"the first to be left out",则"remaining amount"平分给这些员工。
merge into employees e
using ( select employee_id,
sum (salary) over (order by salary) as sum_salary,
count(salary) over (partition by salary) as cnt
from employees
) x
on ( e.employee_id = x.employee_id )
when matched then update
set salary = 1.2 * salary + case when sum_salary <= 100000 / 0.2 then 0
else (100000 - 0.2 * sum_salary) / cnt end
where sum_salary - cnt * salary <= 100000 / 0.2
;