Você precisa de uma única linha por fatura, então agregue
payment_invoice
primeiro - melhor antes de entrar.Quando toda a mesa é selecionada, normalmente é mais rápido agregar primeiro e ingresse mais tarde :
SELECT to_char(date_trunc('month', i.create_datetime), 'MM/YYYY') AS month
, count(*) AS total_invoice_count
, (sum(i.total) - COALESCE(sum(pi.paid), 0)) AS outstanding_balance
FROM invoice i
LEFT JOIN (
SELECT invoice_id AS id, sum(amount) AS paid
FROM payment_invoice pi
GROUP BY 1
) pi USING (id)
GROUP BY date_trunc('month', i.create_datetime)
ORDER BY date_trunc('month', i.create_datetime);
LEFT JOIN
é essencial aqui. Você não quer perder faturas que não tenham linhas correspondentes em payment_invoice
(ainda), o que aconteceria com um simples JOIN
. Assim, use
COALESCE ()
para a soma dos pagamentos, que pode ser NULL. SQL Fiddle com caso de teste melhorado.