#sql #sql-server
#sql #sql-сервер
Вопрос:
У меня есть запрос для извлечения непогашенных платежей из базы данных, который представляет собой общую сумму счета за вычетом общей суммы платежа. Проблема в том, что, когда по счету-фактуре нет платежей, они просто не отображаются. Я хочу, чтобы отображались эти суммы счетов, при этом их общая сумма платежа была равна нулю. Вот мой запрос:
SELECT DISTINCT Client.FirstName ' ' Client.LastName AS
[Client Name],
SUM(Invoices.InvoiceAmount) AS
[Total Invoice Amounts],
SUM(ClientPayments.PaymentAmount) AS
[Total Amount Paid],
SUM(Invoices.InvoiceAmount - ClientPayments.PaymentAmount) AS
[Outstanding Payment Amount]
FROM Invoices
INNER JOIN ClientPayments
ON Invoices.InvoiceNumberID = ClientPayments.InvoiceNumberID
INNER JOIN Client
ON Invoices.ClientNumberID = Client.ClientNumberID
GROUP BY Client.FirstName,
Client.LastName
Спасибо,
Эми
Комментарии:
1. какой SQL… SQL Server, MySQL, ???
Ответ №1:
Вероятно, это основано на выполнении левого соединения, но получите ли вы фиктивные результаты, если у вас есть один счет, который был оплачен несколько раз (частичные платежи). Будут ли эти уравнения «суммы» подсчитывать сумму счета ДВАЖДЫ, например: по одному для каждого частичного платежа? Я бы попробовал следующим образом.
SELECT
C.ClientNumberID,
C.FirstName ' ' C.LastName AS ClientName,
SUM( I.InvoiceAmount ) TotalInvoices,
SUM( CP.PaymentAmount ) AS TotalAmountPaid,
SUM( I.InvoiceAmount ) - SUM( CP.PaymentAmount ) AS OutstandingPaymentAmount
FROM
Invoices I
JOIN Clients C
on I.ClientNumberID = C.ClientNumberID
LEFT JOIN ClientPayments CP
on I.InvoiceNumberID = CP.InvoiceNumberID
GROUP BY
I.ClientNumberID
ORDER BY
C.LastName,
C.FirstName
Обратите внимание, что моя ГРУППА ПО номеру клиента… Что произошло бы в противном случае, если бы у вас было 5 клиентов «Уильям Смит» или «Роберт Браун», которые можно было бы считать «общим именем». Вы же не хотите давать некоему Уильяму Смиту заявление, в котором говорилось, что он задолжал 5000 долларов, когда полностью оплатил все свои покупки, в то время как счета были фактически разделены между другими клиентами «William Smith». ЗАТЕМ ORDER BY разместит их в любом порядке, который вам нужен … или на основе непогашенной суммы по убыванию для самых больших коллекций вверху.
Комментарии:
1. 1 пример:
GROUP BY I.ClientNumberID
а затем «ВЫБЕРИТЕ C.ClientNumberID»?2. 2 пример: что делать, если один счет-фактура (сумма 1000) содержит два платежа (50 и 800)? СУММА (InvoiceAmount) — СУММА (PaymentAmount) = (1000 1000) — (50 800) = 2000 — 850 = 1150 ( неправильно) вместо 150 (ок)
3. 3 пример.:
GROUP BY I.ClientNumberID
и тогдаSELECT c.FirstName ' ' ...
?4. @Amy, хотя вы приняли мой ответ в качестве решения, я на самом деле не пытался выполнить запрос, чтобы обеспечить сценарий, представленный Богданом, как указано выше… Не могли бы вы подтвердить, что мои экземпляры SUM() работают правильно в случае одного счета с несколькими частичными платежами по нему?
Ответ №2:
Попробуйте изменить INNER JOIN
на LEFT JOIN
для первого соединения в вашем запросе
Комментарии:
1. Хорошо, это выводит имена людей, которые ничего не заплатили, но общая сумма платежа равна нулю, как и сумма задолженности. Как мне сделать так, чтобы общая сумма платежа отображала нули, а непогашенная сумма была полной суммой счета-фактуры? (таким образом, сумма счета — 0 = непогашенная сумма)?
2. Если вы используете T-SQL (MS SQL Server), вы можете использовать
ISNULL
function для этого. Итак, первая часть запроса будет выглядеть так:SELECT DISTINCT Client.FirstName ' ' Client.LastName AS [Client Name], SUM(Invoices.InvoiceAmount) AS [Total Invoice Amounts], ISNULL(SUM(ClientPayments.PaymentAmount), 0) AS [Total Amount Paid], ISNULL(SUM(Invoices.InvoiceAmount - ClientPayments.PaymentAmount) , SUM(Invoices.InvoiceAmount))AS [Outstanding Payment Amount]