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

使用mysql更新表贡献计算的触发器,mysql,triggers,calculation,Mysql,Triggers,Calculation,我需要计算每个开发商的项目基础上的贡献 Contribution table ------------------------------------------------------------- | id | projected | developer id | total hours | contribution| ------------------------------------------------------------- | 1 | 1 | 1

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

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
这是我的代码,在这段代码中,其他计算工作正常 捐款不正确


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

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 ;

假设任务记录了开发人员在项目上的工作时间,那么可能会发生2种情况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)

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

而不是触发和更新汇总表,为什么不直接使用对第一个表的查询来获得结果?这可能是在最初插入贡献记录时在您的另一个问题中的触发器中计算出来的。要求是生成一个触发器以更新表上的贡献您可以生成上一个触发器以同时获得此结果吗?我不知道该怎么做你在这个话题上的前一个问题提到了一个任务表(你应该把它带到这个问题中),但我不清楚任务包含哪些信息,或者它是如何维护的。任务是否捕获了开发人员在项目上花费的时间?每个程序员/任务是否有许多条目(即许多插入)?任务可以被更新和插入吗?我没有办法测试它。错误消息的全文是什么?我更新了我的代码,它可以工作,但没有更正,告诉我它不正确本身并没有多大帮助。怎么了?具体点。或者看看它是如何计算并修复的。你的代码不起作用,但使用该代码我现在构建了一个新触发器,它可以工作了。多亏了你,我更新了工作代码。检查它,但贡献计算不正确