chaturIQ
Thinking habit: Count rows before you add them

Why SUM is too big after a JOIN in SQL (rows fan out)

The question: For each customer, show the total value of their orders and the total they have paid.

orders

order_idcustomeramount
1Asha500
2Ravi300
3Asha200

payments

payment_idorder_idpaid
11200
21300
32300
43200

This query looks right. Run it, decide if it is, and fix it.

Show the answer and why the first query is wrong

Why the usual answer is wrong

SELECT o.customer, SUM(o.amount) AS ordered, SUM(p.paid) AS paid
FROM orders o
JOIN payments p ON p.order_id = o.order_id
GROUP BY o.customer;

Order 1 was paid in two parts, so the join gives it two rows and its 500 is added twice. Asha shows 1,200 ordered instead of 700.

The answer

SELECT o.customer, SUM(o.amount) AS ordered, SUM(p.paid) AS paid
FROM orders o
LEFT JOIN (
  SELECT order_id, SUM(paid) AS paid FROM payments GROUP BY order_id
) p ON p.order_id = o.order_id
GROUP BY o.customer;

Add up payments per order first, so each order meets one row. Then the join can't repeat an order and its amount is counted once.

Before you SUM after a join, ask: can one row on the left match many on the right? If so, aggregate that side first.

With subqueries per customer

SELECT o.customer, SUM(o.amount) AS ordered,
  (SELECT SUM(p.paid) FROM payments p
   JOIN orders x ON x.order_id = p.order_id
   WHERE x.customer = o.customer) AS paid
FROM orders o
GROUP BY o.customer;

Practise more like this, on real business data

324 interview-style questions on 35 tables with the duplicates, NULLs and missing weeks interviewers test. Free.

Open the lesson

More SQL interview questions