2013-02-23 9 views
6

Tôi có hai bảngChọn sum và bên tham gia

  • Bills: id amount reference

  • Transactions: id reference amount

Truy vấn SQL sau

SELECT 
    *, 
    (SELECT SUM(amount) 
    FROM transactions 
    WHERE transactions.reference = bils.reference) AS paid 
FROM bills 
GROUP BY id HAVING paid<amount 

có nghĩa là một số hàng từ bảng Bills, thêm cột paid với tổng số tiền của các giao dịch có liên quan.

Tuy nhiên, nó chỉ hoạt động khi có ít nhất một giao dịch cho mỗi hóa đơn. Nếu không, không có dòng nào cho một hóa đơn ít giao dịch được trả về.

Có lẽ, đó là vì tôi nên tham gia vào bên trong!

Vì vậy, tôi thử như sau:

SELECT 
    *, 
    (SELECT SUM(transactions.amount) 
    FROM transactions 
    INNER JOIN bills ON transactions.reference = bills.reference) AS paid 
FROM bills 
GROUP BY id 
HAVING paid < amount 

Tuy nhiên, điều này trả về giá trị cùng trả tiền cho tất cả các hàng! Tôi đang làm gì sai?

Trả lời

15

Sử dụng một trái tham gia thay vì một subquery:

select b.id, b.amount, b.paid, sum(t.amount) as transactionamount 
from bills b 
left join transactions t on t.reference = b.reference 
group by b.id, b.amount, b.paid 
having b.paid < b.amount 

Edit:
Để so sánh tổng các giao dịch để số tiền , xử lý giá trị null mà bạn nhận được khi không có giao dịch:

having isnull(sum(t.amount), 0) < b.amount 
+1

Nhưng không có cột "trả tiền" trong 'Hóa đơn', điều này phải được xác định là tổng số tiền của giao dịch.Nếu tôi cố sửa đổi nó để sửa nó, tôi vẫn chỉ nhận được hàng 'Bills' với ít nhất một giao dịch. – Klaus

+0

@Klaus: Tôi hiểu, đó là nơi bạn có được từ ... Số tiền sẽ là null nếu không có giao dịch, vì vậy bạn sẽ cần phải xử lý điều đó. Xem mã ở trên. – Guffa

+0

Cảm ơn rất nhiều, các 'ifnull' (không' isnull') và trái tham gia đã làm các trick! – Klaus

2

Bạn cần RIGHT JOIN để bao gồm tất cả các hàng hóa đơn.

EDIT Vì vậy, các truy vấn cuối cùng sẽ được

SELECT 
    *, 
    (SELECT SUM(transactions.amount) 
    FROM transactions 
    WHERE transactions.reference = bills.reference) AS paid 
FROM bills 
WHERE paid < amount 
+0

Điều đó sẽ trả lại tổng của tất cả các giao dịch cho tất cả các hóa đơn. – Guffa

+0

Vẫn còn vấn đề tương tự như trong lần thử thứ hai của tôi, như @Guffa mô tả. – Klaus

+0

Nếu bạn thay "INNER JOIN bills ON" bằng "WHERE" – dotNET

0

Tôi biết chủ đề này là cũ, nhưng tôi đến đây ngày hôm nay bởi vì tôi gặp phải cùng một vấn đề.

Hãy xem một bài với cùng một câu hỏi: Sum on a left join SQL

Như câu trả lời cho biết, sử dụng GROUP BY trên bảng bên trái. Bằng cách này, bạn lấy tất cả các bản ghi từ bảng bên trái, và nó tính tổng các hàng tương ứng từ bảng bên phải.

Cố gắng sử dụng này:

SELECT 
    *, 
    SUM(transactions.sum) 
FROM 
    bills 
RIGHT JOIN 
    transactions 
ON 
    bills.reference = transactions.reference 
WHERE 
    transactions.sum > 0 
GROUP BY 
    bills.id