Reputation: 135
I have a trigger that calculates the sum using a previous row and a current row and outputs the sum in balance field of the current row,The problem is that it doesnt seem to calculate the sum of the first row inserted into the table my trigger is:
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;
#
This query returned what i want.. but it doesnt seem to convert to a trigger...
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
Upvotes: 0
Views: 162
Reputation: 51888
Please have a try with this one:
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 $$
I don't know, what your table structure looks like, but you might as well forget about the trigger and just do
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;
or as a trigger
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 $$
If all this doesn't help, sample data and desired result would be helpful, preferably on http://sqlfiddle.com
Upvotes: 1