根据前一行余额更新总计

时间:2016-02-26 09:01:32

标签: mysql sql

这是数据库数据。

Name   id  Col1  Col2  Col3 Col4 Total  Balance
Row1   1    6     1     A     Z     -      - 
Row2   2    2     3     B     Z     -      - 
Row3   3    9     5     B     Y     -      - 
Row4   4    16    8     C     Y     -      -

我想用条件更新Row2到Row4的“Total”和“Balance”列。这是总列总和的逻辑:

  

如果Col3 = A且Col4<> Z,则更新Total = Col1 + Col2   或
  如果Col3 = B且Col4< Z>则总计= Col1-Col2   OR
  如果Col3 = C且Col4< Z>,则总= Col1 * Col2

并且还会更新余额,

  

balance =上一行余额+当前行总数

4 个答案:

答案 0 :(得分:2)

这是一个带有一个用户变量辅助的解决方案。

结果已通过附带的完整演示验证。

SQL:

-- data preparation for demo
create table tbl(Name char(100), id int, Col1 int, Col2 int, Col3 char(20), Col4 char(20), Total int, Balance int);
insert into tbl values
('Row1',1,6,1,'A','Z',0,0),
('Row2',2,2,3,'B','Z',0,0),
('Row3',3,9,5,'B','Y',0,0),
('Row4',4,12,8,'C','Y',0,0);
SELECT * FROM tbl;

-- Query needed
SET @bal = 0;
UPDATE tbl
SET
    Total = CASE    WHEN Col3 = 'A' and Col4 <> 'Z'
                        THEN Col1+Col2
                    WHEN Col3 = 'B' and Col4 <> 'Z'
                        THEN Col1-Col2
                    WHEN Col3 = 'C' and Col4 <> 'Z'
                        THEN Col1*Col2
                    ELSE 0 END,
    Balance = (@bal:=@bal + Total);
SELECT * FROM tbl;

输出(如预期):

mysql> SELECT * FROM tbl;
+------+------+------+------+------+------+-------+---------+
| Name | id   | Col1 | Col2 | Col3 | Col4 | Total | Balance |
+------+------+------+------+------+------+-------+---------+
| Row1 |    1 |    6 |    1 | A    | Z    |     0 |       0 |
| Row2 |    2 |    2 |    3 | B    | Z    |     0 |       0 |
| Row3 |    3 |    9 |    5 | B    | Y    |     0 |       0 |
| Row4 |    4 |   12 |    8 | C    | Y    |     0 |       0 |
+------+------+------+------+------+------+-------+---------+
4 rows in set (0.00 sec)

mysql> -- Query needed
mysql> SET @bal = 0;
Query OK, 0 rows affected (0.00 sec)

mysql> UPDATE tbl
    -> SET
    ->     Total = CASE    WHEN Col3 = 'A' and Col4 <> 'Z'
    ->                         THEN Col1+Col2
    ->                     WHEN Col3 = 'B' and Col4 <> 'Z'
    ->                         THEN Col1-Col2
    ->                     WHEN Col3 = 'C' and Col4 <> 'Z'
    ->                         THEN Col1*Col2
    ->                     ELSE 0 END,
    ->     Balance = (@bal:=@bal + Total);
Query OK, 2 rows affected (0.00 sec)
Rows matched: 4  Changed: 2  Warnings: 0

mysql>
mysql> SELECT * FROM tbl;
+------+------+------+------+------+------+-------+---------+
| Name | id   | Col1 | Col2 | Col3 | Col4 | Total | Balance |
+------+------+------+------+------+------+-------+---------+
| Row1 |    1 |    6 |    1 | A    | Z    |     0 |       0 |
| Row2 |    2 |    2 |    3 | B    | Z    |     0 |       0 |
| Row3 |    3 |    9 |    5 | B    | Y    |     4 |       4 |
| Row4 |    4 |   12 |    8 | C    | Y    |    96 |     100 |
+------+------+------+------+------+------+-------+---------+
4 rows in set (0.00 sec)

答案 1 :(得分:1)

UPDATE tableName t1 SET 
Total =  
CASE
  WHEN t1.Col3 = "A" and t1.Col4 <> "Z" THEN t1.Col1 + t1.Col2
  WHEN t1.Col3 = "B" and t1.Col4 <> "Z" THEN t1.Col1 - t1.Col2
  WHEN t1.Col3 = "C" and t1.Col4 <> "Z" THEN t1.Col1 * t1.Col2
END
Balance = 
CASE
  WHEN t1.Col3 = "A" and t1.Col4 <> "Z" THEN 
  (SELECT t2.Balance FROM tableName t2 
    WHERE t2.id = (select max(t3.id) from tableName t3 where t3.id < t1.id))
    + (t1.Col1 + t1.Col2)
  WHEN t1.Col3 = "B" and t1.Col4 <> "Z" THEN 
  (SELECT t2.Balance FROM tableName t2 
    WHERE t2.id = (select max(t3.id) from tableName t3 where t3.id < t1.id))
    + (t1.Col1 - t1.Col2)
  WHEN t1.Col3 = "C" and t1.Col4 <> "Z" THEN 
  (SELECT t2.Balance FROM tableName t2 
    WHERE t2.id = (select max(t3.id) from tableName t3 where t3.id < t1.id))
    + (t1.Col1 * t1.Col2)
END
WHERE t1.id > 1;

答案 2 :(得分:1)

试试这个

 SET @old_balance = 0;
    UPDATE tableName SET 
    Total =  
    CASE
      WHEN Col3 = 'A' and Col4 <> 'Z' THEN Col1 + Col2
      WHEN Col3 = 'B' and Col4 <> 'Z' THEN Col1 - Col2
      WHEN Col3 = 'C' and Col4 <> 'Z' THEN Col1 * Col2
    END,
    Balance = 
    CASE
      WHEN Col3 = 'A' and Col4 <> 'Z' THEN 
      @old_balance + (Col1 + Col2)
      WHEN Col3 = 'B' and Col4 <> 'Z' THEN 
      @old_balance + (Col1 - Col2)
      WHEN Col3 = 'C' and Col4 <> 'Z' THEN 
      @old_balance + (Col1 * Col2)
    END,
    @old_balance := 
    CASE
      WHEN Col3 = 'A' and Col4 <> 'Z' THEN 
      @old_balance + (Col1 + Col2)
      WHEN Col3 = 'B' and Col4 <> 'Z' THEN 
      @old_balance + (Col1 - Col2)
      WHEN Col3 = 'C' and Col4 <> 'Z' THEN 
      @old_balance + (Col1 * Col2)
    END
    WHERE t1.id > 1;

答案 3 :(得分:1)

SET @prev_id = 1;
UPDATE tableName SET 
Total =  
CASE
  WHEN Col3 = A and Col4 <> Z THEN Col1 + Col2
  WHEN Col3 = B and Col4 <> Z THEN Col1 - Col2
  WHEN Col3 = C and Col4 <> Z THEN Col1 * Col2
END,
Balance = 
CASE
  WHEN Col3 = A and Col4 <> Z THEN 
  (SELECT Balance FROM tableName WHERE id = @prev_id) + (Col1 + Col2)
  WHEN Col3 = B and Col4 <> Z THEN 
  (SELECT Balance FROM tableName WHERE id = @prev_id) + (Col1 - Col2)
  WHEN Col3 = C and Col4 <> Z THEN 
  (SELECT Balance FROM tableName WHERE id = @prev_id) + (Col1 * Col2)
END,
@prev_id := id

WHERE t1.id > 1;