2012-02-22 2 views
5

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

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 

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

ответ

14

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

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

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 согласован, так как в противном случае баланс будет варьироваться в зависимости от того, какой порядок возвращают строки. Если вы хотите, чтобы затем заказать его обратно на фронт, к примеру, вы могли бы использовать это в качестве подзапроса как тогда внешние сделки запроса с таким образом, вычисленные значения обеспечения баланса остается правильным IE

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 
+0

как с нумерацией страниц, я думаю, что этот запрос не будет работать хорошо, баланс не будет хорошо –

+0

@PutraLZendrato я боюсь, что я не понимаю, вопрос –

+1

Привет Саймон, я имею в виду, как если данные строка большая, например, у нас есть 100 данных, но не будет загружаться на одной странице. Таким образом, мы разделяем на 2 страницы (работающая с разбивкой по страницам). Я думаю, что работающий баланс не будет работать. –

3

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

SELECT `ID`, 
     `In`, 
     `Out`, 
     @running_bal := @running_bal + (`In` - `Out`) as `Balance` 
FROM tableName, (SELECT @running_bal := 0) tempName 
0

простой 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; 
Смежные вопросы