【问题标题】:MySQL triggers and SUM()MySQL 触发器和 SUM()
【发布时间】:2015-12-06 00:31:56
【问题描述】:

我有两张桌子学生和家庭。在学生中,我有列 st_income 和 total_income。在家里,我有收入。 Total_income 是学生的 st_income 和 family.id_student=student.id_student 的家庭收入的总和。

我想通过触发器更新 total_income,我做了这个

CREATE TRIGGER family_income_update AFTER UPDATE ON `family` 
FOR EACH ROW UPDATE student SET total_income= ((SELECT SUM(income) 
FROM family WHERE family.id_student=student.id_student)+
(SELECT st_income FROM student WHERE student.id_student=NEW.id_student)) 
WHERE student.id_student=NEW.id_student 

MySQL 接受了这个触发器,但是当我想更新表族中的归档收入时,我得到了这样的沟通:

1093 - 您不能在 FROM 子句中指定目标表 'student' 进行更新

我不知道如何解决这个问题。

更新

我试过这个:

CREATE TRIGGER family_income_update AFTER UPDATE ON `family` 
FOR EACH ROW 

SET @familyIncome = SELECT SUM(income) FROM family WHERE family.id_student=student.id_student
SET @studentIncome= SELECT st_income FROM student WHERE student.id_student=NEW.id_student
SET @totalIncome=@familyIncome+@studentIncome

UPDATE student SET total_income=@totalIncome WHERE student.id_student=NEW.id_student

但我得到了这个答案:

1064 - 您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 4 行的“SELECT SUM(income) FROM family WHERE family.id_student=student.id_student”附近使用正确的语法

更新

我尝试添加到 st_income 的 total_income 值。两列都在同一个表中。我试过这个:

CREATE TRIGGER `st_income_update` AFTER UPDATE ON `student`
 FOR EACH ROW BEGIN
  UPDATE student
    SET total_income = total_income + (NEW.st_income - OLD.st_income)
    WHERE student.id_student = NEW.id_student;
END

但它会导致错误。

【问题讨论】:

    标签: mysql triggers


    【解决方案1】:

    这就是所谓的“变异表”问题。归结为,不允许行触发器访问同一个表中的其他行,因为不能保证行将按特定顺序更新等等。

    首先,当您可以在需要时轻松计算时,您真的不应该尝试存储 total_income。也就是说,我认为你可以通过做类似的事情来做你想做的事

    CREATE TRIGGER family_income_update
      AFTER UPDATE ON family
      FOR EACH ROW 
    BEGIN
      UPDATE student
        SET total_income = total_income + (NEW.income - OLD.income)
        WHERE student.id_student = NEW.id_student;
    END;
    

    这个想法是修改 student.total_income 相对于其先前的值,因为您只能引用 family.income 相对于其先前的值。

    【讨论】:

    • 我不知道为什么会这样:#1064 - 您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 7 行的 '' 附近使用正确的语法
    【解决方案2】:

    尝试在选择中重命名学生表的别名

    CREATE TRIGGER family_income_update AFTER UPDATE ON `family` 
    FOR EACH ROW UPDATE student SET total_income= ((SELECT SUM(income) 
    FROM family WHERE family.id_student=student.id_student)+
    (SELECT b.st_income FROM student as b WHERE  b.id_student=NEW.id_student)) 
    WHERE student.id_student=NEW.id_student 
    

    【讨论】:

      【解决方案3】:

      如果您在触发器中使用变量来计算总收入,然后在更新查询中使用该变量?

      类似的东西

      CREATE TRIGGER family_income_update AFTER UPDATE ON `family` 
      FOR EACH ROW 
      
      SET @totalIncome=(SELECT (st.st_income + ifnull(fam.income, 0)) as     total_income
                        FROM student st left join (
                                  SELECT id_student, SUM(income) as income
                                  FROM family
                                  GROUP BY id_student
                              ) fam on fam.id_student = st.id_student
                        WHERE st.id_student = NEW.id_student);
      
      UPDATE student 
      SET total_income = @totalIncome 
      WHERE student.id_student=NEW.id_student;
      

      【讨论】:

      • #1064 - 您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 6 行的“UPDATE student SET total_income=@totalIncome WHERE student.id_student=NEW.id_stu”附近使用正确的语法
      • 我已编辑我的答案以更改查询以从家庭和学生表中获取总收入并将其放入变量中
      猜你喜欢
      • 2017-02-25
      • 1970-01-01
      • 1970-01-01
      • 2013-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多