Рассчитать баланс с MySQL - PullRequest
       30

Рассчитать баланс с MySQL

5 голосов
/ 22 февраля 2012

У меня есть таблица, которая содержит следующие данные:

ID      In       Out 
1      100.00    0.00   
2       10.00    0.00   
3        0.00   70.00    
4        5.00    0.00    
5        0.00   60.00   
6       20.00    0.00     

Теперь мне нужен запрос, который дает мне следующий результат:

ID      In       Out    Balance
1      100.00    0.00   100.00
2       10.00    0.00   110.00
3        0.00   70.00    40.00
4        5.00    0.00    45.00
5        0.00   60.00   -15.00
6       20.00    0.00     5.00

Можно ли сделать это одним запросом, без использования триггера или хранимых процедур?

Ответы [ 3 ]

16 голосов
/ 22 февраля 2012

Краткий ответ, да

Более длинный ответ, вы можете использовать переменную, чтобы подсчитать ее, пока она перебирает строки, то есть

SELECT 
    `table`.`ID`,
    `table`.`In`,
    `table`.`Out`,
    @Balance := @Balance + `table`.`In` - `table`.`Out` AS `Balance`
FROM `table`, (SELECT @Balance := 0) AS variableInit
ORDER BY `table`.`ID` ASC

, (SELECT @Balance := 0) AS variableInit гарантирует, что @Balance инициализируется до 0, прежде чем начать. Затем для каждой строки устанавливается значение @Balance @Balance + In - Out, а затем выводится рассчитанное значение.

Также стоит удостовериться, что ORDER согласован, иначе баланс будет меняться в зависимости от того, в каком порядке возвращаются строки. Если вы хотите затем упорядочить его, например, обратно, вы можете использовать его как подзапрос, так как тогда внешний запрос обрабатывает вычисленные значения, таким образом гарантируя, что Баланс остается правильным, т.е.

SELECT
    `balanceCalculation`.`ID`,
    `balanceCalculation`.`In`,
    `balanceCalculation`.`Out`,
    `balanceCalculation`.`Balance`
FROM (
    SELECT 
        `table`.`ID`,
        `table`.`In`,
        `table`.`Out`,
        @Balance := @Balance + `table`.`In` - `table`.`Out` AS `Balance`
    FROM `table`, (SELECT @Balance := 0) AS variableInit
    ORDER BY `table`.`ID` ASC
) AS `balanceCalculation`
ORDER BY `balanceCalculation`.`ID` DESC
3 голосов
/ 22 февраля 2012

Самый простой ответ будет:

SELECT `ID`, 
       `In`, 
       `Out`, 
       @running_bal := @running_bal + (`In` - `Out`)  as `Balance`
FROM   tableName, (SELECT @running_bal := 0) tempName
0 голосов
/ 27 января 2017

Достаточно простого LEFT JOIN:

SELECT t.ID, t.In, t.Out, (SUM(t2.In) - SUM(t2.Out)) Balance
FROM mytable t
    LEFT JOIN mytable t2 ON b2.ID <= b.ID
GROUP BY b.ID

Или подзапрос (который, как выясняется, примерно в два раза быстрее)

SELECT t.ID, t.In, t.Out,
    (SELECT SUM(t2.In) - SUM(t2.Out) FROM mytable t2 WHERE t2.ID <= t.ID) Balance
FROM mytable t;
...