我正在尝试创建一个MySQL触发器,如果更新了级别奖励,它将更新我的所有用户分数。我已经解决了旧奖励和新奖励之间的差异,但我仍然坚持如何更新已经完成该等级的每个用户分数。下面是一个简化的表格结构。
Users
+---------+-------+
| user_id | score |
+---------+-------+
Users_levels
+---------+----------+
| user_id | level_id |
+---------+----------+
Levels
+----------+---------+
| level_id | tier_id |
+----------+---------+
Tier_reward
+---------+----------+
| tier_id | reward |
+---------+----------+
到目前为止我已经走了多远:
CREATE TRIGGER update_level_reward AFTER UPDATE ON tier_reward FOR EACH ROW
BEGIN
DECLARE REWARD INT;
SET REWARD = OLD.reward - NEW.reward;
-- UPDATE users SET score = score - REWARD WHERE user_id = ;
END$$
我尝试了以下方面的内容:
UPDATE users
INNER JOIN users_levels
ON users.user_id = users_levels.user_id
INNER JOIN levels
ON users_levels.level_id = levels.level_id
SET score = score - REWARD
WHERE levels.tier = OLD.tier;
然而,即使用户已完成该级别的多个级别,这也只会降低一次得分。
示例
Users
+---------+-------+
| user_id | score |
+---------+-------+
| 1 | 400 |
| 2 | 700 |
+---------+-------+
Users_levels
+---------+----------+
| user_id | level_id |
+---------+----------+
| 1 | 1 |
| 1 | 2 |
| 2 | 1 |
| 2 | 3 |
+---------+----------+
Levels
+----------+---------+
| level_id | tier_id |
+----------+---------+
| 1 | 1 |
| 2 | 1 |
| 3 | 2 |
+----------+---------+
Tier_reward
+---------+----------+
| tier_id | reward |
+---------+----------+
| 1 | 200 |
| 2 | 500 |
+---------+----------+
现在,如果tier_id 1的奖励减少到100.用户1现在应该得分为200,因为他们已完成该等级的两个级别。用户2应该只丢失100分,因为他们只完成了该级别的一个级别。
Users
+---------+-------+
| user_id | score |
+---------+-------+
| 1 | 200 |
| 2 | 600 |
+---------+-------+
Tier_reward
+---------+----------+
| tier_id | reward |
+---------+----------+
| 1 | 100 |
| 2 | 500 |
+---------+----------+
答案 0 :(得分:1)
抱歉延迟!!
您可以执行以下操作,首先需要获得每个用户的每个层数。然后使用cursor设置这些值,最后更新users表。
delimiter //
create trigger update_level_reward after update on tier_reward
for each row
begin
DECLARE done INT DEFAULT FALSE;
DECLARE tier_count int;
DECLARE user_id_fetch int;
DECLARE reward INT;
DECLARE reward_recal int ;
DECLARE cur CURSOR FOR
select
ul.user_id, count(*) as total
from users_levels ul
join levels l on l.level_id = ul.level_id
where l.tier_id = new.tier_id
group by ul.user_id;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
SET reward = OLD.reward - NEW.reward;
OPEN cur;
update_loop: LOOP
FETCH cur INTO user_id_fetch,tier_count;
IF done THEN
LEAVE update_loop;
END IF;
set reward_recal = tier_count*reward ;
update users
SET score = score - reward_recal
where user_id = user_id_fetch ;
END LOOP;
CLOSE cur;
end ; //
delimiter ;
这是我在mysql中所做的事情
create table users (user_id int,score int);
insert into users values (1,400),(2,700);
create table users_levels(user_id int,level_id int);
insert into users_levels values
(1,1),(1,2),(2,1),(2,3);
create table levels (level_id int,tier_id int);
insert into levels values
(1,1),(2,1),(3,2);
create table tier_reward(tier_id int,reward int);
insert into tier_reward values
(1,200),(2,500);
mysql> update tier_reward set reward = 100 where tier_id = 1 ;
Query OK, 1 row affected (0.15 sec)
mysql> select * from users ;
+---------+-------+
| user_id | score |
+---------+-------+
| 1 | 200 |
| 2 | 600 |
+---------+-------+
2 rows in set (0.00 sec)