Вам понадобится пара подзапросов, чтобы удовлетворить ваши требования. Давайте разберемся с этим.
Во-первых, вам нужна общая стоимость заказов от каждого клиента. Вы очень близки к правильному запросу для этого. Это должно быть
SELECT orders.customerNumber,
SUM(orderdetails.quantityOrdered * orderdetails.priceEach) owed
FROM orders
JOIN orderdetails ON orders.orderNumber = orderdetails.orderNumber
GROUP BY orders.customerNumber
Этот результирующий набор подзапроса дает customerNumber и задолженность, причитающуюся сумму. Обратите внимание, что orders :: orderdetails является отношением one :: many, поэтому мы уверены, что мы учитываем каждую деталь только один раз, поэтому суммы SUM будут правильными.
Далее нам нужна сумма, выплачиваемая каждым клиентом. , Этот подзапрос довольно прост.
SELECT customerNumber,
SUM(amount) paid
FROM payments
GROUP BY customerNumber
Теперь для операции, которая вам не хватает в вашем вопросе: нам нужно присоединить эти два подзапроса к таблице ваших клиентов.
SELECT customers.customerName, customers.customerNumber
owed.owed - paid.paid balance
FROM customers
LEFT JOIN (
SELECT orders.customerNumber,
SUM(orderdetails.quantityOrdered * orderdetails.priceEach) owed
FROM orders
JOIN orderdetails ON orders.orderNumber = orderdetails.orderNumber
GROUP BY orders.customerNumber
) paid ON customers.customerNumber = paid.customerNumber
LEFT JOIN (
SELECT customerNumber,
SUM(amount) paid
FROM payments
GROUP BY customerNumber
) owed ON customers.customerNumber = owed.customerNumber
Посмотрите, как это работает? Мы объединяем таблицу и два подзапроса. Каждый подзапрос имеет либо ноль, либо одну строку для каждой строки в таблице, поэтому нам не нужно использовать SUMs или GROUP BY во внешнем запросе.
Осталось только одно осложнение: что, если клиент никогда ничего не платил? Тогда значение paid.paid будет равно NULL после операции LEFT JOIN. Это заставит значение owed - paid
быть NULL. Поэтому нам нужно больше умов в операторе SELECT, чтобы получить правильные суммы.
SELECT customers.customerName, customers.customerNumber
COALESCE(owed.owed,0) - COALESCE(paid.paid,0) balance
...
COALESCE (a, b) эквивалентно , если a не равно нулю, тогда a else b .
Pro tip В запросах или подзапросах с операциями JOIN всегда указывайте table.column
вместо column
. Следующий человек, который будет работать над вашим запросом, поблагодарит вас.