【问题标题】:How to add a rest of salary to each employee per MANAGER_ID using SQL如何使用 SQL 为每个 MANAGER_ID 的每个员工添加剩余的工资
【发布时间】:2019-02-12 09:59:37
【问题描述】:

我对主题中的案例有疑问。我想减去两个金额之间的剩余部分。

如果有一个值 > 0,那么我想为每个按 MANAGER_ID 分区的员工添加其余部分,但每 1 美分。

例如:其余的是 0,04 美元,我有 3 名员工,由同一位经理领导。我将选择员工 ID 的最大值并将 0,01$ 添加到记录中,第二个获得 0,01$,下一个获得 0,01$,员工 ID 的最大值再次获得 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

【问题讨论】:

标签: sql database oracle oracle11g


【解决方案1】:

类似这样的:

dbfiddle demo

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 中,您可以更清楚地看到每个部分。

【讨论】:

    【解决方案2】:

    这是一个基于数学商和模型的解决方案。

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-30
      • 2016-11-15
      • 1970-01-01
      • 2019-06-23
      • 1970-01-01
      • 1970-01-01
      • 2018-03-27
      • 2016-04-14
      相关资源
      最近更新 更多