I believe this question has been here for several times but I haven't found a straightforward solution in answers here on Stack.
My question is when I have 1:n relationship and using LEFT JOIN on A table rows where there can be multiple B rows for one A row, how to get sum of values in A?
Let's say I have A table orders
and B table transactions
for orders
. There can be multiple transactions for one order. Here's an example query:
CREATE TABLE `orders` (
`id` int(11) NOT NULL,
`price` decimal(10,2) DEFAULT '0.00'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `transactions` (
`id` int(11) NOT NULL,
`order_id` int(11) DEFAULT NULL,
`amount` decimal(10,2) DEFAULT '0.00'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO `orders` (`id`, `price`)
VALUES
(1, 330.00),
(2, 800.00);
INSERT INTO `transactions` (`id`, `order_id`, `amount`)
VALUES
(1, 1, 330.00),
(2, 2, 200.00),
(3, 2, 200.00),
(4, 2, 200.00);
Then when I try to sum up price of orders:
SELECT o.id, sum(o.price) from orders o
LEFT JOIN transactions tr ON o.id = tr.order_id
The result for sum(o.price)
is 2730
. It should be 1130
(330+800). Instead, as there are three transactions
for order(2)
, there are 3 transaction
rows for that order made by LEFT JOIN in the result and therefore the calculation is 330+800*3
. I tried using GROUP BY o.id
but the sum is probably calculated before the GROUP BY
( http://sqlfiddle.com/#!9/82bd8/8/0 )
How can I make the sum to show the correct value but preserve the LEFT JOIN?
Do the sum before the join
. Your query is a bit non-sensical because it has no information from transactions
. But the idea is:
select o.*, t. . . .
from orders o
(select t.order_id, . . .
from transactions t
group by t.order_id
) t
on o.id = t.order_id;
You're getting 2730 because your join isn't linear to your main data set. While my suggested answer is not the most efficient way to do this I believe it handles your situation.
SELECT
orders.id,
(SELECT SUM(price) FROM orders) AS 'price'
FROM
orders
LEFT JOIN
transactions ON
transactions.order_id = orders.id
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.