2012-02-22 42 views
5

Tính tôi có một bảng chứa các dữ liệu sau:cân bằng với 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  

Bây giờ tôi cần một truy vấn mà mang lại cho tôi những kết quả sau:

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 

Có thể làm điều này với một truy vấn, không sử dụng trình kích hoạt hoặc thủ tục được lưu trữ?

Trả lời

14

Câu trả lời ngắn, có câu trả lời

dài hơn, bạn có thể sử dụng một biến để kiểm đếm nó lên như nó lặp xuống dòng, tức là

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 

Các , (SELECT @Balance := 0) AS variableInit đảm bảo rằng @Balance được khởi tạo vào 0 trước bạn bắt đầu. Đối với mỗi hàng, nó sẽ đặt @Balance thành @Balance + In - Out và sau đó xuất ra giá trị được tính.

Cũng đáng để đảm bảo rằng ORDER nhất quán nếu không, Số dư sẽ khác nhau tùy thuộc vào thứ tự các hàng được trả về. Nếu bạn muốn sau đó đặt nó trở lại phía trước, ví dụ, bạn có thể sử dụng điều này như một subquery như sau đó các giao dịch truy vấn bên ngoài với các giá trị tính toán đảm bảo các cân đối vẫn còn đúng nghĩa là

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

cách với pagination, tôi nghĩ rằng truy vấn này sẽ không hoạt động tốt, sự cân bằng sẽ không tiến triển tốt –

+0

@PutraLZendrato Tôi sợ tôi không hiểu câu hỏi –

+1

Xin chào Simon, ý tôi là, làm thế nào nếu các dữ liệu hàng là lớn, Ví dụ, chúng tôi có 100 dữ liệu, nhưng sẽ không tải trong một trang. Vì vậy, chúng tôi tách thành 2 trang (phân trang làm việc). Tôi nghĩ rằng số dư hoạt động sẽ không hoạt động. –

3

Câu trả lời đơn giản nhất sẽ là:

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

Một đơn giản LEFT JOIN sẽ đủ:

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 

Hoặc subquery (mà khi nó quay ra là về nhanh gấp hai lần)

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; 
Các vấn đề liên quan