patternsqlMinor
Update column with the sum of column in previous rows in MySQL
Viewed 0 times
rowstheupdatepreviouscolumnwithmysqlsum
Problem
We have a table, essentially:
id, amount, end balance, account_id
I now want to re-calculate the end balance values (because of possible corruption)
End balance is basically "end balance of previous entry with the same account_id" + amount.
Assume that there are a lot of entries, but I want to do this for one account at a time (or for a couple of accounts).
(So, if we have the corrupt table:
I want the resulting db table to be:
)
id, amount, end balance, account_id
I now want to re-calculate the end balance values (because of possible corruption)
End balance is basically "end balance of previous entry with the same account_id" + amount.
Assume that there are a lot of entries, but I want to do this for one account at a time (or for a couple of accounts).
(So, if we have the corrupt table:
Id Amount Balance Account
1 100 0 1
2 100 100 2
3 -40 -40 1
4 100 60 1I want the resulting db table to be:
Id Amount Balance Account
1 100 100 1
2 100 100 2
3 -40 60 1
4 100 160 1)
Solution
Let make the table called
Let's run that code and Make the Data:
Here is the Query You Need
Here is that Query Executed:
That's it !!!
If other accounts are messed up in the same way, set
Here is That Code Formatted:
Give it a Try !!!
nuoji and load it with the above dataUSE test
DROP TABLE IF EXISTS nuoji;
CREATE TABLE nuoji
(
id int not null auto_increment primary key,
amount INT NOT NULL,
balance INT NOT NULL,
account INT NOT NULL,
KEY (account)
) ENGINE=MyISAM;
INSERT INTO nuoji (amount,balance,account) VALUES
(100,100,1),(100,100,2),(-40,-40,1),(100,60,1);
SELECT * FROM nuoji;Let's run that code and Make the Data:
mysql> USE test
Database changed
mysql> DROP TABLE IF EXISTS nuoji;
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE nuoji
-> (
-> id int not null auto_increment primary key,
-> amount INT NOT NULL,
-> balance INT NOT NULL,
-> account INT NOT NULL,
-> KEY (account)
-> ) ENGINE=MyISAM;
Query OK, 0 rows affected (0.05 sec)
mysql> INSERT INTO nuoji (amount,balance,account) VALUES
-> (100,100,1),(100,100,2),(-40,-40,1),(100,60,1);
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM nuoji;
+----+--------+---------+---------+
| id | amount | balance | account |
+----+--------+---------+---------+
| 1 | 100 | 100 | 1 |
| 2 | 100 | 100 | 2 |
| 3 | -40 | -40 | 1 |
| 4 | 100 | 60 | 1 |
+----+--------+---------+---------+
4 rows in set (0.00 sec)
mysql>Here is the Query You Need
SET @rt=0; SET @ndx=0; SET @given_account=1;
UPDATE nuoji A INNER JOIN (SELECT * FROM
(SELECT (@ndx:=@ndx+1) ndx,id,amount,
(@rt:=@rt+amount) newbalance FROM nuoji
WHERE account=@given_account) BB) B USING (id)
SET A.balance=B.newbalance;Here is that Query Executed:
mysql> SET @rt=0; SET @ndx=0; SET @given_account=1;
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
mysql> UPDATE nuoji A INNER JOIN (SELECT * FROM
-> (SELECT (@ndx:=@ndx+1) ndx,id,amount,
-> (@rt:=@rt+amount) newbalance FROM nuoji
-> WHERE account=@given_account) BB) B USING (id)
-> SET A.balance=B.newbalance;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 3 Changed: 0 Warnings: 0
mysql> SELECT * FROM nuoji;
+----+--------+---------+---------+
| id | amount | balance | account |
+----+--------+---------+---------+
| 1 | 100 | 100 | 1 |
| 2 | 100 | 100 | 2 |
| 3 | -40 | 60 | 1 |
| 4 | 100 | 160 | 1 |
+----+--------+---------+---------+
4 rows in set (0.00 sec)
mysql>That's it !!!
If other accounts are messed up in the same way, set
@given_account, and then execute the code.Here is That Code Formatted:
SET @rt = 0;
SET @ndx = 0;
SET @given_account = 1;
UPDATE
nuoji A INNER JOIN
(
SELECT * FROM
(
SELECT
(@ndx:=@ndx+1) ndx,id,
amount,(@rt:=@rt+amount) newbalance
FROM nuoji
WHERE account=@given_account
) BB
) B USING (id)
SET A.balance=B.newbalance;Give it a Try !!!
Code Snippets
USE test
DROP TABLE IF EXISTS nuoji;
CREATE TABLE nuoji
(
id int not null auto_increment primary key,
amount INT NOT NULL,
balance INT NOT NULL,
account INT NOT NULL,
KEY (account)
) ENGINE=MyISAM;
INSERT INTO nuoji (amount,balance,account) VALUES
(100,100,1),(100,100,2),(-40,-40,1),(100,60,1);
SELECT * FROM nuoji;mysql> USE test
Database changed
mysql> DROP TABLE IF EXISTS nuoji;
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE nuoji
-> (
-> id int not null auto_increment primary key,
-> amount INT NOT NULL,
-> balance INT NOT NULL,
-> account INT NOT NULL,
-> KEY (account)
-> ) ENGINE=MyISAM;
Query OK, 0 rows affected (0.05 sec)
mysql> INSERT INTO nuoji (amount,balance,account) VALUES
-> (100,100,1),(100,100,2),(-40,-40,1),(100,60,1);
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM nuoji;
+----+--------+---------+---------+
| id | amount | balance | account |
+----+--------+---------+---------+
| 1 | 100 | 100 | 1 |
| 2 | 100 | 100 | 2 |
| 3 | -40 | -40 | 1 |
| 4 | 100 | 60 | 1 |
+----+--------+---------+---------+
4 rows in set (0.00 sec)
mysql>SET @rt=0; SET @ndx=0; SET @given_account=1;
UPDATE nuoji A INNER JOIN (SELECT * FROM
(SELECT (@ndx:=@ndx+1) ndx,id,amount,
(@rt:=@rt+amount) newbalance FROM nuoji
WHERE account=@given_account) BB) B USING (id)
SET A.balance=B.newbalance;mysql> SET @rt=0; SET @ndx=0; SET @given_account=1;
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
mysql> UPDATE nuoji A INNER JOIN (SELECT * FROM
-> (SELECT (@ndx:=@ndx+1) ndx,id,amount,
-> (@rt:=@rt+amount) newbalance FROM nuoji
-> WHERE account=@given_account) BB) B USING (id)
-> SET A.balance=B.newbalance;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 3 Changed: 0 Warnings: 0
mysql> SELECT * FROM nuoji;
+----+--------+---------+---------+
| id | amount | balance | account |
+----+--------+---------+---------+
| 1 | 100 | 100 | 1 |
| 2 | 100 | 100 | 2 |
| 3 | -40 | 60 | 1 |
| 4 | 100 | 160 | 1 |
+----+--------+---------+---------+
4 rows in set (0.00 sec)
mysql>SET @rt = 0;
SET @ndx = 0;
SET @given_account = 1;
UPDATE
nuoji A INNER JOIN
(
SELECT * FROM
(
SELECT
(@ndx:=@ndx+1) ndx,id,
amount,(@rt:=@rt+amount) newbalance
FROM nuoji
WHERE account=@given_account
) BB
) B USING (id)
SET A.balance=B.newbalance;Context
StackExchange Database Administrators Q#56378, answer score: 3
Revisions (0)
No revisions yet.