使用mysql更新表贡献计算的触发器

eiee3dmh  于 2021-06-21  发布在  Mysql
关注(0)|答案(2)|浏览(363)

我需要计算每个开发商的项目基础上的贡献

Contribution table
-------------------------------------------------------------
| id | projected | developer id | total hours | contribution|
-------------------------------------------------------------
| 1  | 1         |  1           |      25     |             |
-------------------------------------------------------------
| 2  | 1         |  2           |      75     |             |
-------------------------------------------------------------
| 3  | 2         |  1           |      10     |             |
-------------------------------------------------------------

需要在插入和更新预期结果之后使用触发器更新同一个表

Contribution table
    -------------------------------------------------------------
    | id | projected | developer id | total hours | contribution|
    -------------------------------------------------------------
    | 1  | 1         |  1           |      25     |   25%       |
    ------------------------------------------------------------
    | 2  | 1         |  2           |      75     |   75%       |
    -------------------------------------------------------------
    | 3  | 2         |  1           |      10     |   100%      |
    -------------------------------------------------------------

获得贡献的计算
项目1:
总小时数=25+75=100每位开发者贡献=25/100*100=25%
我需要一个触发器来得到这个结果:但我不知道如何得到这个结果
这是我的触发器没有得到错误,但贡献计算不正确

CREATE TRIGGER `update_contribution` AFTER INSERT ON `tasks`
 FOR EACH ROW BEGIN 
 IF NOT EXISTS 
 (SELECT p_id ,d_id 
  FROM contribution 
  WHERE 
  p_id = NEW.p_id 
  AND 
  d_id = NEW.d_id) 
  THEN

 SET @old_total_dev_hours = (SELECT SUM(total_hours)             
                       FROM contribution 
                       WHERE p_id = NEW.p_id
                       GROUP BY p_id);

 SET @total_hours1 = (SELECT (total_hours)             
                       FROM contribution 
                       WHERE d_id = NEW.d_id AND p_id = NEW.p_id
                       );

  SET @dev_con =  @total_hours1/@old_total_dev_hours*100 ;

  SET @total_hours =  new.hours + new.overtime;
  INSERT INTO contribution
    ( p_id,
     d_id,
     hours,
     overtime,
     total_hours,
     contribution
    )
   VALUES
   (NEW.p_id,
    NEW.d_id,
    NEW.hours,
    NEW.overtime,
      @total_hours ,
    @dev_con
   );
 ELSE
   UPDATE contribution 
   SET 
   hours = hours + NEW.hours , 
   overtime = overtime + NEW.overtime, 
   total_hours = hours + overtime,
   contribution = @dev_con
   WHERE 
   p_id = NEW.p_id 
   AND 
   d_id = NEW.d_id;
   END IF;
   END

这是我的代码,在这个代码中其他计算都很好,贡献得不正确!!

avwztpqn

avwztpqn1#

假设任务记录了开发人员在项目上的工作时间,那么可能会发生两件事1)没有注意到开发人员在贡献中已经在项目上工作了2)开发人员已经在项目上工作了,他工作的时间需要在贡献中更新。这两种情况都意味着每个任务的插入都需要重新计算所有开发人员的贡献。
例如

drop table if exists t,contribution;
create table t(id int auto_increment primary key, developerid int, projectid int,hrs_normal int, hrs_overtime int);
create table contribution(id int auto_increment primary key, projectid int,
developerid int, hrs int, contribution decimal (6,3) default 0);

drop trigger if exists t;
delimiter $$
create trigger t after insert on t
for each row 
begin
declare totalhours int default 0;
    set totalhours = (select ifnull(sum(hrs),0) from contribution where projectid = new.projectid);
    set totalhours = totalhours + ifnull(new.hrs_normal,0) + ifnull(new.hrs_overtime,0);
    if not exists (select 1 from contribution where projectid = new.projectid and developerid = new.developerid) then
        insert into contribution(projectid,developerid,hrs) 
        values
        (new.projectid,new.developerid,ifnull(new.hrs_normal,0) + ifnull(new.hrs_overtime,0)
        );
    else 
        update contribution
            set hrs = hrs + ifnull(new.hrs_normal,0) + ifnull(new.hrs_overtime,0)
            where developerid = new.developerid and projectid = new.projectid;
    end if;

    update contribution
        set contribution = (hrs / totalhours) * 100
        where projectid = new.projectid;

end $$
delimiter ;

MariaDB [sandbox]> truncate table t;
Query OK, 0 rows affected (0.28 sec)

MariaDB [sandbox]> truncate table contribution;
Query OK, 0 rows affected (0.25 sec)

MariaDB [sandbox]> select * from t;
Empty set (0.00 sec)

MariaDB [sandbox]> select * from contribution;
Empty set (0.00 sec)

MariaDB [sandbox]>
MariaDB [sandbox]> insert into t (developerid , projectid ,hrs_normal , hrs_overtime )
    -> values
    -> (1,1,10,0);
Query OK, 1 row affected (0.02 sec)

MariaDB [sandbox]>
MariaDB [sandbox]> select * from t;
+----+-------------+-----------+------------+--------------+
| id | developerid | projectid | hrs_normal | hrs_overtime |
+----+-------------+-----------+------------+--------------+
|  1 |           1 |         1 |         10 |            0 |
+----+-------------+-----------+------------+--------------+
1 row in set (0.00 sec)

MariaDB [sandbox]> select * from contribution;
+----+-----------+-------------+------+--------------+
| id | projectid | developerid | hrs  | contribution |
+----+-----------+-------------+------+--------------+
|  1 |         1 |           1 |   10 |      100.000 |
+----+-----------+-------------+------+--------------+
1 row in set (0.00 sec)

MariaDB [sandbox]>
MariaDB [sandbox]> insert into t (developerid , projectid ,hrs_normal , hrs_overtime )
    -> values
    -> (1,1,10,0),(2,1,30,10);
Query OK, 2 rows affected (0.05 sec)
Records: 2  Duplicates: 0  Warnings: 0

MariaDB [sandbox]>
MariaDB [sandbox]> select * from t;
+----+-------------+-----------+------------+--------------+
| id | developerid | projectid | hrs_normal | hrs_overtime |
+----+-------------+-----------+------------+--------------+
|  1 |           1 |         1 |         10 |            0 |
|  2 |           1 |         1 |         10 |            0 |
|  3 |           2 |         1 |         30 |           10 |
+----+-------------+-----------+------------+--------------+
3 rows in set (0.00 sec)

MariaDB [sandbox]> select * from contribution;
+----+-----------+-------------+------+--------------+
| id | projectid | developerid | hrs  | contribution |
+----+-----------+-------------+------+--------------+
|  1 |         1 |           1 |   20 |       33.333 |
|  2 |         1 |           2 |   40 |       66.667 |
+----+-----------+-------------+------+--------------+
2 rows in set (0.00 sec)

MariaDB [sandbox]>
MariaDB [sandbox]> insert into t (developerid , projectid ,hrs_normal , hrs_overtime )
    -> values
    -> (1,1,10,0),(2,2,30,10);
Query OK, 2 rows affected (0.05 sec)
Records: 2  Duplicates: 0  Warnings: 0

MariaDB [sandbox]>
MariaDB [sandbox]> select * from t;
+----+-------------+-----------+------------+--------------+
| id | developerid | projectid | hrs_normal | hrs_overtime |
+----+-------------+-----------+------------+--------------+
|  1 |           1 |         1 |         10 |            0 |
|  2 |           1 |         1 |         10 |            0 |
|  3 |           2 |         1 |         30 |           10 |
|  4 |           1 |         1 |         10 |            0 |
|  5 |           2 |         2 |         30 |           10 |
+----+-------------+-----------+------------+--------------+
5 rows in set (0.00 sec)

MariaDB [sandbox]> select * from contribution;
+----+-----------+-------------+------+--------------+
| id | projectid | developerid | hrs  | contribution |
+----+-----------+-------------+------+--------------+
|  1 |         1 |           1 |   30 |       42.857 |
|  2 |         1 |           2 |   40 |       57.143 |
|  3 |         2 |           2 |   40 |      100.000 |
+----+-----------+-------------+------+--------------+
3 rows in set (0.00 sec)

注意,如果业务规则是开发人员可以在任务中修改的,那么您还需要按照同样的思路更新触发器。

pvabu6sv

pvabu6sv2#

这是一个更新的触发器,它将取代您之前问题中的触发器。它同时计算总时数和贡献百分比。

DELIMITER |

CREATE TRIGGER update_hours AFTER INSERT ON tasks
FOR EACH ROW 
BEGIN
    SET @old_total_dev_hours = (SELECT SUM(hours + overtime)
        FROM contribution 
        WHERE p_id == new.p_id && d_id == new.d_id 
        GROUP BY p_id,d_id);
    SET @old_total_hours = (SELECT SUM(hours + overtime)
        FROM contribution 
        WHERE p_id == new.p_id
        GROUP BY p_id);

    SET @total_hours = @old_total_dev_hours + new.hours + new.overtime;
    SET @contrib_percent = (@old_total_dev_hours / @old_total_hours) * 100;

    INSERT INTO contribution
    ( p_id,
    d_id,
    hours,
    overtime,
    total_hours,
    contribution )
    VALUES
    ( 
        NEW.p_id,
        NEW.d_id,
        NEW.hours,
        NEW.overtime,
        @total_hours,
        @contrib_percent
    );
END|

DELIMITER ;

相关问题