Vous avez besoin d'une seule ligne par facture, donc agrégez payment_invoice
d'abord - de préférence avant de rejoindre.
Lorsque toute la table est sélectionnée, il est généralement plus rapide de agréger d'abord et rejoindre plus tard
:
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
est essentiel ici. Vous ne voulez pas perdre des factures qui n'ont pas de lignes correspondantes dans payment_invoice
(encore), ce qui arriverait avec un simple JOIN
.
En conséquence, utilisez COALESCE()
pour la somme des paiements, qui peut être NULL.
SQL Fiddle avec un scénario de test amélioré.