2014-05-20 42 views
0

我有一个触发器,它使用前一行和当前行计算总和,并输出当前行的平衡字段中的总和,问题是它似乎没有计算第一行插入到表中我的触发器:触发器没有正确计算总和MySQL

delimiter $$ 
CREATE TRIGGER `ledger_calc` AFTER INSERT ON `sp_records` 
FOR EACH ROW BEGIN 
SET @PrevBal := (SELECT balance FROM ledger WHERE cmp_name = NEW.cmp_name AND inv_for = NEW.inv_for ORDER BY id DESC 
LIMIT 1); 
SET @CmpName := NEW.cmp_name; 
SET @InvFor := NEW.inv_for; 

IF (NEW.type = 'sales') THEN 
SET @Type := 'sales'; 

INSERT INTO ledger (id,inv_for,cmp_name,date,debit,balance) 
SELECT 
     TransactDet.id, 
    TransactDet.inv_for, 
    TransactDet.cmp_name, 
     TransactDet.date, 
     TransactDet.tot_amnt, 
     @PrevBal := @PrevBal + TransactDet.tot_amnt as balance 
    from 
     (select 
       Transact.id, 
       Transact.date, 
       Transact.tot_amnt, 
       Transact.cmp_name, 
       Transact.inv_for 

      from 
       sp_records Transact 
      where Transact.type = @Type 
      AND Transact.inv_for = @InvFor 
      AND Transact.cmp_name = @CmpName 
      order by 
      Transact.id DESC 
      limit 1) as TransactDet; 
ELSE 
SET @Type := 'purchase'; 
INSERT INTO ledger (id,inv_for,cmp_name,date,credit,balance) 
SELECT 
     TransactDet.id, 
    TransactDet.inv_for, 
    TransactDet.cmp_name, 
     TransactDet.date, 
     TransactDet.tot_amnt, 
     @PrevBal := @PrevBal - TransactDet.tot_amnt as balance 
    from 
     (select 
       Transact.id, 
       Transact.date, 
       Transact.tot_amnt, 
       Transact.cmp_name, 
       Transact.inv_for 
      from 
       sp_records Transact 
      where Transact.type = @Type 
      AND Transact.inv_for = @InvFor 
      AND Transact.cmp_name = @CmpName 
      order by 
      Transact.id DESC 
      limit 1) as TransactDet; 
END IF; 

END; 

该查询返回我想要的..但​​它似乎没有转化为触发...

SELECT 
     PreAgg.id, 
     PreAgg.tot_amnt, 
     @PrevBal := @PrevBal + PreAgg.tot_amnt as balance 
    from 
     (select 
       YT.id, 
       YT.tot_amnt 
      from 
       sp_records YT 
      order by 
       YT.id) as PreAgg, 
     (select @PrevBal := 0.00) as SqlVars 

回答

1

请有试试这个:

delimiter $$ 

CREATE TRIGGER `ledger_calc` BEFORE INSERT ON `sp_records` 
FOR EACH ROW 
BEGIN 
    SET @PrevBal : = (
      SELECT balance 
      FROM ledger 
      WHERE cmp_name = NEW.cmp_name 
       AND inv_for = NEW.inv_for 
      ORDER BY id DESC LIMIT 1 
      ); 

    INSERT INTO ledger (id, inv_for, cmp_name, DATE, debit, balance) 
    SELECT Transact.id, Transact.inv_for, Transact.cmp_name, Transact.DATE, Transact.tot_amnt, @PrevBal + Transact.tot_amnt AS balance 
    FROM sp_records Transact 
    WHERE Transact.type = NEW.type 
     AND Transact.inv_for = NEW.inv_for 
     AND Transact.cmp_name = NEW.cmp_name 
    ORDER BY Transact.id DESC limit 1; 
END $$ 

我不知道,你的表结构是什么样子,但你不如忘了扳机,只是做

INSERT INTO ledger (id, inv_for, cmp_name, DATE, debit, balance) 
SELECT t.id, t.inv_for, t.cmp_name, t.DATE, t.tot_amnt, l.balance + t.tot_amnt AS balance 
FROM sp_records t 
INNER JOIN ledger l ON t.inv_for = l.inv_for AND t.cmp_name = l.cmp_name 
WHERE t.type = 'a_value' 
    AND t.inv_for = 'another_value' 
    AND t.cmp_name = 'yet_another_value' 
ORDER BY t.id DESC limit 1; 

或作为触发

DELIMITER $$ 
CREATE TRIGGER `ledger_calc` AFTER INSERT ON `sp_records` 
FOR EACH ROW 
BEGIN 
    INSERT INTO ledger (id, inv_for, cmp_name, DATE, debit, balance) 
    SELECT t.id, t.inv_for, t.cmp_name, t.DATE, t.tot_amnt, l.balance + t.tot_amnt AS balance 
    FROM sp_records t 
    INNER JOIN ledger l ON t.inv_for = l.inv_for AND t.cmp_name = l.cmp_name 
    WHERE t.type = NEW.type 
     AND t.inv_for = NEW.inv_for 
     AND t.cmp_name = NEW.cmp_name 
    ORDER BY t.id DESC limit 1; 
END $$ 

如果所有这些都无济于事,则样本数据和期望的结果将会有所帮助,最好在http://sqlfiddle.com

+0

我已更新我的问题pl轻松检查出来 – MoniXx

+0

我已经更新了我的答案,请检查出来。 – fancyPants

+0

@MoniXx当你想把它写成触发器时,会出现什么问题?你也应该发布你尝试的整个触发器,否则不清楚触发器应该做什么。 – fancyPants