Reputation: 523
I have a table Invoice with a column total. Then I have a table Payments with a column amount (Usually there are several payments to one invoice). I need a column balance which is the difference of Invoice.Total - (total of payments made on that invoice). This is what I have (Oh ya using Azure Sql Server)
select I.Invoice_Id,
I.Total - (select sum(Amount) from Payments P
where I.Invoice_Id = P.Invoice_Id) as Balance,
Q.Quote_Id,
Q.Description,
Q.Vendor_Num
from Invoice as I
inner join Payments as P on I.Invoice_Id = P.Invoice_Id
inner join Quote as Q on Q.Quote_Id = I.Quote_Id;
Eventually this will be a view showing what invoices have balance owed. If I remove the where in the sub query it gives me an answer but it is the sum of all payments. I just want the sum of payments made on that invoice. Any help would be appreciated.
Thanks
Upvotes: 4
Views: 4772
Reputation: 297
There's two approaches to this. You could either subquery or group by. If you're doing a subquery you don't need the table in the main query. Also the inner join to Payments would mean that invoices without payment would not be returned by the query. Changing it to a left outer join in the Group By example will return NULL rows when the I.Invoice_Id = P.Invoice_Id
is not met.
Group By:
SELECT I.Invoice_Id,
I.Total - sum(ISNULL(P.Amount,0)) AS Balance,
Q.Quote_Id,
Q.Description,
Q.Vendor_Num
FROM Invoice AS I
JOIN Quote AS Q on Q.Quote_Id = I.Quote_Id
LEFT JOIN Payments AS P on I.Invoice_Id = P.Invoice_Id
GROUP BY I.Invoice_Id, I.Total, Q.Quote_Id, Q.Description, Q.Vendor_Num
Subquery:
SELECT I.Invoice_Id,
I.Total - (SELECT ISNULL(SUM(Amount),0) FROM Payments P WHERE P.Invoice_Id = I.Invoice_Id) AS Balance,
Q.Quote_Id,
Q.Description,
Q.Vendor_Num
FROM Invoice AS I
JOIN Quote AS Q on Q.Quote_Id = I.Quote_Id
Upvotes: 2
Reputation: 62831
I suspect your query is returning multiple results (duplicates per payment) since you are joining
on the payments
table.
One option would be to just remove that join
to the payments
table. Here's an alternative option which moves the correlated subquery
to a join
:
select I.Invoice_Id,
I.Total - p.SumAmount as Balance,
Q.Quote_Id,
Q.Description,
Q.Vendor_Num
from Invoice as I
inner join Quote as Q on Q.Quote_Id = I.Quote_Id;
inner join (
select invoice_id, sum(amount) SumAmount
from Payments
group by invoice_id) as P on I.Invoice_Id = P.Invoice_Id
Upvotes: 0