Bạn vẫn chưa cung cấp thông tin đầy đủ - không có bảng lô, thậm chí không có bảng đối ứng hiện có .. Dù sao, tôi cho rằng chúng ta không quan tâm đến những gì trong bảng lô, hãy nói rằng đó chỉ là tên và id. Bảng biên lai của bạn có nhiều hàng cho cùng một học sinh. Điều này cũng sẽ dẫn đến nhiều hàng được trả về cho các bảng khác, do tất cả các JOIN. Do đó, bạn SUM () nhiều lần các giá trị phải được tính tổng chỉ một lần, tức là open_balance. Đây có thể là manh mối cho biết vấn đề nằm ở đâu, tôi muốn nói rằng bạn phải chuyển thông tin mà bạn cần từ 'bảng biên lai vào các truy vấn con, nhưng tôi không chắc bạn đã cho chúng tôi xem toàn bộ DB của mình. Thử xóa bảng biên nhận khỏi truy vấn và kiểm tra lại kết quả. Nếu đúng như vậy, bạn nên xem những việc cần làm từ đó trở đi hoặc ít nhất hãy cung cấp thêm thông tin cho chúng tôi.
CHỈNH SỬA: Truy vấn phải là:
SELECT
b.name AS batch_name,
b.id AS batch_id,
COUNT(DISTINCT s.id)
AS total_students,
COALESCE( SUM(s.open_bal), 0 )
AS open_balance,
SUM( COALESCE(i.reg_fee, 0)
+ COALESCE(i.tut_fee, 0)
+ COALESCE(i.other_fee, 0)
) AS gross_fee,
SUM( COALESCE(i.discount, 0) )
AS discount,
COALESCE( SUM(s.open_bal), 0 )
+ SUM( COALESCE(i.reg_fee, 0)
+ COALESCE(i.tut_fee, 0)
+ COALESCE(i.other_fee, 0)
)
- SUM( COALESCE(i.discount, 0) )
AS net_payable,
SUM((SELECT SUM(COALESCE(receipts.reg_fee, 0)
+ COALESCE(receipts.tut_fee, 0)
+ COALESCE(receipts.other_fee, 0)) FROM receipts WHERE receipts.student_id = s.id))
AS net_recieved,
( COALESCE( SUM(s.open_bal), 0 )
+ SUM( COALESCE(i.reg_fee, 0)
+ COALESCE(i.tut_fee, 0)
+ COALESCE(i.other_fee, 0)
)
- SUM( COALESCE(i.discount, 0) )
)
- SUM((SELECT SUM(COALESCE(receipts.reg_fee, 0)
+ COALESCE(receipts.tut_fee, 0)
+ COALESCE(receipts.other_fee, 0)) FROM receipts WHERE receipts.student_id = s.id))
AS balance_due
FROM batches b
LEFT JOIN students s ON s.batch = b.id
LEFT JOIN invoices i ON i.student_id = s.id
WHERE s.inactive = 0
GROUP BY b.name, b.id;
Điều này sẽ tổng hợp dữ liệu học sinh trong bảng biên nhận ngay cả khi nó nằm trên nhiều hàng, chỉ trả về một hàng. Việc xóa liên kết với bảng biên nhận sẽ xóa các dòng trùng lặp từ các bảng khác, vì vậy các phép tính bây giờ sẽ chính xác.
Một điều nữa - bạn đã có s.inactive = 0
trong mệnh đề WHERE, hãy đảm bảo rằng nó không liên quan đến tính toán này.
P.S. Tại sao bạn không biết truy vấn phụ là gì và cuối cùng bạn lại viết những thứ như thế?