Несколько объединений с группировкой и производными таблицами
У меня есть четыре таблицы MySQL: контакты, заказы, order_products и продукты, и я пытаюсь написать несколько отчетов. Вот один из них:
SELECT t1.name, t1.contact_id, SUM(t1.prodSoldQty) AS contactSoldQty, SUM(t1.prodSoldVol) AS soldVol
FROM contacts
INNER JOIN
(
SELECT
contacts.name,
ordered_products.product_id,
ordered_products.contact_id,
SUM(ordered_products.quantity) AS prodSoldQty,
(products.price * SUM(ordered_products.quantity)) AS prodSoldVol
FROM ordered_products
INNER JOIN contacts ON contacts.id = ordered_products.contact_id
INNER JOIN products ON products.id = ordered_products.product_id
INNER JOIN orders ON orders.id = ordered_products.order_id
GROUP BY ordered_products.product_id , ordered_products.contact_id
ORDER BY ordered_products.product_id
) AS t1 ON t1.contact_id = contacts.id
GROUP BY contacts.id
ORDER BY t1.name;
Все работает, как и ожидалось, хотя, если я добавлю (и мне нужно добавить) еще одно [LEFT|INNER] JOIN (например, INNER JOIN orders ON orders.contact_id = contacts.id) строки, итоговые суммы которых испортились (кажется, они дубликаты, дубликаты... в зависимости от количества заказов). Я предполагаю, что проблема может быть в множественной группировке в первой производной таблице соединения. Все же это ускользает от меня. Здесь вы можете найти слегка вариант вышеуказанного запроса. Даже эта крошечная модификация способна вызвать "проблему":
SELECT t1.name, t1.contact_id,
SUM(t1.prodSoldQty) AS contactSoldQty,
SUM(t1.prodSoldVol) AS soldVol
FROM contacts
INNER JOIN
(
SELECT
contacts.name,
ordered_products.product_id,
ordered_products.contact_id,
SUM(ordered_products.quantity) AS prodSoldQty,
(products.price * SUM(ordered_products.quantity)) AS prodSoldVol
FROM ordered_products
INNER JOIN contacts ON contacts.id = ordered_products.contact_id
INNER JOIN products ON products.id = ordered_products.product_id
INNER JOIN orders ON orders.id = ordered_products.order_id
GROUP BY ordered_products.product_id , ordered_products.contact_id
ORDER BY ordered_products.product_id
) AS t1 ON t1.contact_id = contacts.id
INNER JOIN orders ON orders.contact_id = contacts.id
WHERE orders.order_state_id != '111'
GROUP BY contacts.id
ORDER BY t1.name;
Вышеуказанный путь - тупик. С помощью @Gordon Linoff я смог найти лучший путь. Одна из целей отчетности состояла в том, чтобы рассчитать общую стоимость продукта и общую сумму продажи продукта по клиенту / контактной базе. Я был сосредоточен на том, чтобы сделать это с двумя отдельными соединениями. Кажется, что этого будет достаточно (избегая включать в себя несколько раз почти одинаковые таблицы):
SELECT t1.name, t1.contact_id,
SUM(t1.prodSellQty) AS sellQty,
SUM(t1.prodCostVol) AS costAmount,
SUM(t1.prodSellVol) AS sellAmount
FROM contacts
INNER JOIN
(
SELECT
contacts.name,
ordered_products.contact_id,
SUM(ordered_products.quantity) AS prodSellQty,
SUM(products.price * ordered_products.quantity) AS prodCostVol,
SUM(ordered_products.price * ordered_products.quantity) AS prodSellVol
FROM ordered_products
INNER JOIN contacts ON contacts.id = ordered_products.contact_id
INNER JOIN products ON products.id = ordered_products.product_id
INNER JOIN orders ON orders.id = ordered_products.order_id
GROUP BY ordered_products.product_id , ordered_products.contact_id
ORDER BY ordered_products.product_id
) AS t1 ON t1.contact_id = contacts.id
GROUP BY contacts.id
ORDER BY contacts.name;
Спасибо лука