SQL-запрос — Непогашенные платежи

#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]