Как добавить остаток зарплаты каждому сотруднику за MANAGER_ID с помощью SQL - PullRequest
0 голосов
/ 12 февраля 2019

У меня проблема с делом в теме.Я хотел бы вычесть остаток из двух сумм.

Если есть значение> 0, то я хочу добавить остаток на каждого сотрудника, разделенного по MANAGER_ID, но каждый цент.

Например: остальное - 0,04 $, и у меня три сотрудника под руководством одного и того же менеджера.И я выберу максимальное значение идентификатора сотрудника и добавлю 0,01 $ к записи, второй получу 0,01 $, следующий 0,01 $, и снова максимальное значение идентификатора сотрудника получится на 0,01 $ больше, потому чтоЕсли остаток больше, чем количество сотрудников с тем же руководителем, то цикл будет повторяться.

Другой пример: когда у нас 0,02 $ отдыха и четыре сотрудника, только первые два получат 0,01 $, а последние два 0,00 $.

Как это сделать, используя только SQL?Без PL / SQL.Буду благодарен за любую помощь.

CREATE TABLE TMP_SCKOV_CASE
(MANAGER_ID NUMBER
,EMPLOYEE_ID NUMBER
,AMOUNT NUMBER
,AMOUNT2 NUMBER
);

INSERT INTO TMP_SCKOV_CASE (MANAGER_ID, EMPLOYEE_ID, AMOUNT, AMOUNT2) VALUES (1,122,1053.21, 1053.23);
INSERT INTO TMP_SCKOV_CASE (MANAGER_ID, EMPLOYEE_ID, AMOUNT, AMOUNT2) VALUES (1,123,1053.21, 1053.23);
INSERT INTO TMP_SCKOV_CASE (MANAGER_ID, EMPLOYEE_ID, AMOUNT, AMOUNT2) VALUES (1,124,1053.21, 1053.23);
INSERT INTO TMP_SCKOV_CASE (MANAGER_ID, EMPLOYEE_ID, AMOUNT, AMOUNT2) VALUES (1,125,1053.21, 1053.23);
INSERT INTO TMP_SCKOV_CASE (MANAGER_ID, EMPLOYEE_ID, AMOUNT, AMOUNT2) VALUES (5,126,1229.87, 1229.92);
INSERT INTO TMP_SCKOV_CASE (MANAGER_ID, EMPLOYEE_ID, AMOUNT, AMOUNT2) VALUES (5,127,1229.87, 1229.92);
INSERT INTO TMP_SCKOV_CASE (MANAGER_ID, EMPLOYEE_ID, AMOUNT, AMOUNT2) VALUES (5,128,1229.87, 1229.92);
INSERT INTO TMP_SCKOV_CASE (MANAGER_ID, EMPLOYEE_ID, AMOUNT, AMOUNT2) VALUES (5,129,1229.87, 1229.92);

SELECT T.*, T.AMOUNT2-T.AMOUNT DIFF FROM TMP_SCKOV_CASE T

Ответы [ 2 ]

0 голосов
/ 12 февраля 2019

Примерно так:

Демоверсия dbfiddle

merge into tmp_sckov_case tgt
using (
  with 
    t1 as (
      select t.*, count(1) over (partition by manager_id) cnt, 
             floor(100*(t.amount2 - t.amount)/ count(1) over (partition by manager_id))/100 full_cent 
        from tmp_sckov_case t),
    t2 as (
      select t1.*, (amount2 - amount - cnt * full_cent) / .01 surplus, 
             row_number() over (partition by manager_id order by employee_id) rn
        from t1)
  select manager_id, employee_id, full_cent + case when rn <= surplus then .01 else 0 end rest 
    from t2) src
on (tgt.manager_id = src.manager_id and tgt.employee_id = src.employee_id)
when matched then update set amount = amount + rest

Подзапрос t1 считает полные центы, которыекаждый сотрудник должен получить, для id = 1 это 0, для id = 5 это 1. Подзапрос t2 подсчитывает оставшиеся центы.Последний выбор назначает эти центы с помощью row_number ().

Теперь мы знаем сумму для каждого работника и помещаем наш запрос в merge в качестве исходных данных.В моем dbfiddle вы можете видеть каждую часть более четко.

0 голосов
/ 12 февраля 2019

Вот решение, основанное на коэффициентах математики и модах.

select manager_id, employee_id
,.01 * quot + coalesce((case when rnk <= Remm and quot = 0 then .01
when rnk <= Remm and quot > 0 then .01 *remm
end),0) as value
from 
(select manager_id, employee_id, amount2, amount
, count(employee_id) over(partition by manager_id) tot_employee
, rank() over(partition by manager_id order by employee_id desc) as rnk
,floor(((Amount2-Amount)/.01) / (count(employee_id) over(partition by manager_id)) )  as Quot
,mod(((Amount2-Amount)/.01) , count(employee_id) over(partition by manager_id) ) as remm
from TMP_SCKOV_CASE
) a11
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...