问题
I'm kind of new to MySQL and I need help. I have a table Invoices
and a table Payments
. I am having trouble generating a report that will show all invoices that were paid in In Full
or a Partial Payment
was received by 12/31/2019. One Invoice can be paid by one or more payments (For example a partial payment, such as 25% down, and the remainder payment on completion of work). How can I create SQL query that will select ALL records from Invoices
and then for each Invoice select matching Payment, compare it to the Invoice Total
and will display either Paid in Full
or partial Payment
? I have the following code:
SELECT Invoices.InvoiceID, Invoices.ClientName, Invoices.InvoiceTotal
INNER JOIN InvoiceStatus ON InvoiceStatus.InvoiceStatusID = Invoices.InvoiceStatus
WHERE InvoiceDate BETWEEN '2019-1-1 00:00:00' AND '2019-12-31 23:59:59'
AND (Invoices.InvoiceStatus = '1' OR Invoices.InvoiceStatus = '2')
AND (Invoices.InvoiceActive != 0 OR Invoices.InvoiceActive IS NULL)
ORDER BY ClientName
SELECT Payment.PaymentID, Payment.PaymentReceivedAmount, Payment.PaymentReceivedDate FROM `Payment`
INNER JOIN Invoices ON Invoices.InvoiceID = Payment.InvoiceID
WHERE PaymentReceivedDate BETWEEN '2019-1-1 00:00:00' AND '2019-12-31 23:59:59'
If I do INNER JOIN
then I get two rows for an Invoice that was paid with two payment. I know that I also need to implement IF() statement to show Paid in Full
and Partial Payment
but I'm a little lost. Any help would be greatly appreciated!
回答1:
You can join both tables, aggregate by invoice, and use sum()
to compute the total payment. Finally, a case
expression can be used to display the status:
select i.invoiceid, i.clientname, i.invoicetotal,
coalesce(sum(p.PaymentReceivedAmount), 0) as paymenttotal,
case when i.invoicetotal <=> sum(p.PaymentReceivedAmount) then 'In Full' else 'Partial Payment' end as paymentstatus
from invoices i
left join payment p
on p.invoiceid = i.invoiceid
and p.paymentreceiveddate >= '2019-01-01' and p.paymentreceiveddate < '2020-01-01'
where
i.invoicedate >= '2019-01-01' and i.invoicedate < '2020-01-01'
and i.invoicestatus in (1, 2)
and (i.invoiceactive <> 0 or i.invoiceactive is null)
group by i.invoiceid
order by clientname
Notes:
The
left join
allows invoices without any payment in the period.I used the same date filters as in your original queries, but optimized it a little by turning it to half-open intervals.
It does not seem like you need table
invoicestatus
to achieve the result you want.
来源:https://stackoverflow.com/questions/65097737/mysql-select-and-if-statement