Using SUM with Joins in MySQL returns unexpected result
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
I have these tables : customers, customer_invoices, customer_invoice_details, each customer has many invoices, and each invoice has many details.
The customer with the ID 574413 has these invoices :
select customer_invoices.customer_id,
customer_invoices.id,
customer_invoices.total_price
from customer_invoices
where customer_invoices.customer_id = 574413;
result :
customer_id invoice_id total_price
574413 662146 700.00
574413 662147 250.00
each invoice here has two details (or invoice lines) :
first invoice 662146:
select customer_invoice_details.id as detail_id,
customer_invoice_details.customer_invoice_id as invoice_id,
customer_invoice_details.total_price as detail_total_price
from customer_invoice_details
where customer_invoice_details.customer_invoice_id = 662146;
result :
detail_id invoice_id detail_total_price
722291 662146 500.00
722292 662146 200.00
second invoice 662147 :
select customer_invoice_details.id as detail_id,
customer_invoice_details.customer_invoice_id as invoice_id,
customer_invoice_details.total_price as detail_total_price
from customer_invoice_details
where customer_invoice_details.customer_invoice_id = 662147;
result :
detail_id invoice_id detail_total_price
722293 662147 100.00
722294 662147 150.00
I have a problem with this query :
select customers.id as customerID,
customers.last_name,
customers.first_name,
SUM(customer_invoices.total_price) as invoice_total,
SUM(customer_invoice_details.total_price) as details_total
from customers
join customer_invoices
on customer_invoices.customer_id = customers.id
join customer_invoice_details
on customer_invoice_details.customer_invoice_id = customer_invoices.id
where customer_id = 574413;
unexpected result :
customerID last_name first_name invoice_total details_total
574413 terry amine 1900.00 950.00
I need to have the SUM of the total_price of the invoices, and the SUM of the total_price of the details for each customer. In this case I'm supposed to get 950 as total_price for both columns (invoice_total& details_total) but it's not the case. what am I doing wrong & how can I get the correct result please. The answers in similar topics don't have the solution for this case.
mysql sql join
add a comment |
I have these tables : customers, customer_invoices, customer_invoice_details, each customer has many invoices, and each invoice has many details.
The customer with the ID 574413 has these invoices :
select customer_invoices.customer_id,
customer_invoices.id,
customer_invoices.total_price
from customer_invoices
where customer_invoices.customer_id = 574413;
result :
customer_id invoice_id total_price
574413 662146 700.00
574413 662147 250.00
each invoice here has two details (or invoice lines) :
first invoice 662146:
select customer_invoice_details.id as detail_id,
customer_invoice_details.customer_invoice_id as invoice_id,
customer_invoice_details.total_price as detail_total_price
from customer_invoice_details
where customer_invoice_details.customer_invoice_id = 662146;
result :
detail_id invoice_id detail_total_price
722291 662146 500.00
722292 662146 200.00
second invoice 662147 :
select customer_invoice_details.id as detail_id,
customer_invoice_details.customer_invoice_id as invoice_id,
customer_invoice_details.total_price as detail_total_price
from customer_invoice_details
where customer_invoice_details.customer_invoice_id = 662147;
result :
detail_id invoice_id detail_total_price
722293 662147 100.00
722294 662147 150.00
I have a problem with this query :
select customers.id as customerID,
customers.last_name,
customers.first_name,
SUM(customer_invoices.total_price) as invoice_total,
SUM(customer_invoice_details.total_price) as details_total
from customers
join customer_invoices
on customer_invoices.customer_id = customers.id
join customer_invoice_details
on customer_invoice_details.customer_invoice_id = customer_invoices.id
where customer_id = 574413;
unexpected result :
customerID last_name first_name invoice_total details_total
574413 terry amine 1900.00 950.00
I need to have the SUM of the total_price of the invoices, and the SUM of the total_price of the details for each customer. In this case I'm supposed to get 950 as total_price for both columns (invoice_total& details_total) but it's not the case. what am I doing wrong & how can I get the correct result please. The answers in similar topics don't have the solution for this case.
mysql sql join
1
Your joins are creating multiple records (one for each detail), you will have a total of 950.00 in both of these detail records and since there are 2 rows they are being summed together. You need to include a GROUP BY to your query and this should yield the results you're looking for.
– haag1
Nov 15 '18 at 15:23
add a comment |
I have these tables : customers, customer_invoices, customer_invoice_details, each customer has many invoices, and each invoice has many details.
The customer with the ID 574413 has these invoices :
select customer_invoices.customer_id,
customer_invoices.id,
customer_invoices.total_price
from customer_invoices
where customer_invoices.customer_id = 574413;
result :
customer_id invoice_id total_price
574413 662146 700.00
574413 662147 250.00
each invoice here has two details (or invoice lines) :
first invoice 662146:
select customer_invoice_details.id as detail_id,
customer_invoice_details.customer_invoice_id as invoice_id,
customer_invoice_details.total_price as detail_total_price
from customer_invoice_details
where customer_invoice_details.customer_invoice_id = 662146;
result :
detail_id invoice_id detail_total_price
722291 662146 500.00
722292 662146 200.00
second invoice 662147 :
select customer_invoice_details.id as detail_id,
customer_invoice_details.customer_invoice_id as invoice_id,
customer_invoice_details.total_price as detail_total_price
from customer_invoice_details
where customer_invoice_details.customer_invoice_id = 662147;
result :
detail_id invoice_id detail_total_price
722293 662147 100.00
722294 662147 150.00
I have a problem with this query :
select customers.id as customerID,
customers.last_name,
customers.first_name,
SUM(customer_invoices.total_price) as invoice_total,
SUM(customer_invoice_details.total_price) as details_total
from customers
join customer_invoices
on customer_invoices.customer_id = customers.id
join customer_invoice_details
on customer_invoice_details.customer_invoice_id = customer_invoices.id
where customer_id = 574413;
unexpected result :
customerID last_name first_name invoice_total details_total
574413 terry amine 1900.00 950.00
I need to have the SUM of the total_price of the invoices, and the SUM of the total_price of the details for each customer. In this case I'm supposed to get 950 as total_price for both columns (invoice_total& details_total) but it's not the case. what am I doing wrong & how can I get the correct result please. The answers in similar topics don't have the solution for this case.
mysql sql join
I have these tables : customers, customer_invoices, customer_invoice_details, each customer has many invoices, and each invoice has many details.
The customer with the ID 574413 has these invoices :
select customer_invoices.customer_id,
customer_invoices.id,
customer_invoices.total_price
from customer_invoices
where customer_invoices.customer_id = 574413;
result :
customer_id invoice_id total_price
574413 662146 700.00
574413 662147 250.00
each invoice here has two details (or invoice lines) :
first invoice 662146:
select customer_invoice_details.id as detail_id,
customer_invoice_details.customer_invoice_id as invoice_id,
customer_invoice_details.total_price as detail_total_price
from customer_invoice_details
where customer_invoice_details.customer_invoice_id = 662146;
result :
detail_id invoice_id detail_total_price
722291 662146 500.00
722292 662146 200.00
second invoice 662147 :
select customer_invoice_details.id as detail_id,
customer_invoice_details.customer_invoice_id as invoice_id,
customer_invoice_details.total_price as detail_total_price
from customer_invoice_details
where customer_invoice_details.customer_invoice_id = 662147;
result :
detail_id invoice_id detail_total_price
722293 662147 100.00
722294 662147 150.00
I have a problem with this query :
select customers.id as customerID,
customers.last_name,
customers.first_name,
SUM(customer_invoices.total_price) as invoice_total,
SUM(customer_invoice_details.total_price) as details_total
from customers
join customer_invoices
on customer_invoices.customer_id = customers.id
join customer_invoice_details
on customer_invoice_details.customer_invoice_id = customer_invoices.id
where customer_id = 574413;
unexpected result :
customerID last_name first_name invoice_total details_total
574413 terry amine 1900.00 950.00
I need to have the SUM of the total_price of the invoices, and the SUM of the total_price of the details for each customer. In this case I'm supposed to get 950 as total_price for both columns (invoice_total& details_total) but it's not the case. what am I doing wrong & how can I get the correct result please. The answers in similar topics don't have the solution for this case.
mysql sql join
mysql sql join
edited Nov 15 '18 at 15:15
dwix
asked Nov 15 '18 at 15:09
dwixdwix
2931520
2931520
1
Your joins are creating multiple records (one for each detail), you will have a total of 950.00 in both of these detail records and since there are 2 rows they are being summed together. You need to include a GROUP BY to your query and this should yield the results you're looking for.
– haag1
Nov 15 '18 at 15:23
add a comment |
1
Your joins are creating multiple records (one for each detail), you will have a total of 950.00 in both of these detail records and since there are 2 rows they are being summed together. You need to include a GROUP BY to your query and this should yield the results you're looking for.
– haag1
Nov 15 '18 at 15:23
1
1
Your joins are creating multiple records (one for each detail), you will have a total of 950.00 in both of these detail records and since there are 2 rows they are being summed together. You need to include a GROUP BY to your query and this should yield the results you're looking for.
– haag1
Nov 15 '18 at 15:23
Your joins are creating multiple records (one for each detail), you will have a total of 950.00 in both of these detail records and since there are 2 rows they are being summed together. You need to include a GROUP BY to your query and this should yield the results you're looking for.
– haag1
Nov 15 '18 at 15:23
add a comment |
4 Answers
4
active
oldest
votes
When you mix normal columns with aggregate functions (for example SUM), you need to use GROUP BY where you list the normal columns from the SELECT.
The reason for the excessive amount in total_price for invoices is that the SUM is also calculated over each detail row as it is part of the join. Use this:
select c.id as customerID,
c.last_name,
c.first_name,
SUM(ci.total_price) as invoice_total,
SUM((select SUM(d.total_price)
from customer_invoice_details d
where d.customer_invoice_id = ci.id)) as 'detail_total_price'
from customers c
join customer_invoices ci on ci.customer_id = c.id
where c.id = 574413
group by c.id, c.last_name, c.first_name
db-fiddle
I see, thank you, but your query still doesn't return the correct result. It returns two rows, the first withtotal_price: 250, and the second row withtotal_price: 700, instead of just one row oftotal_price: 950.
– dwix
Nov 15 '18 at 15:35
There was a typo in the code. Corrected.
– slaakso
Nov 15 '18 at 15:47
Changingci.idtoci.invoice_idwasn't the problem. because the column is actuallyid.
– dwix
Nov 15 '18 at 15:50
Forgot to sum the rows together. Done now.
– slaakso
Nov 15 '18 at 15:56
1
Actually, you do not need the outer query as you can do the SUM directly in the main query. Should be even (a bit) faster.
– slaakso
Nov 15 '18 at 16:40
|
show 1 more comment
I used join against sub queries and then did a sum on the sums
SELECT c.id as customerID,
c.last_name,
c.first_name
SUM(i.sum) as invoice_total,
SUM(d.sum) AS details_total
FROM customers c
JOIN (SELECT id, customer_id, SUM(total_price) AS sum
FROM customer_invoices
GROUP BY id, customer_id) AS i ON i.customer_id = c.id
JOIN (SELECT customer_invoice_id as id, SUM(total_price) AS sum
FROM customer_invoice_details
GROUP BY customer_invoice_id) AS d ON d.id = i.id
WHERE c.id = 574413
GROUP BY c.id, c.name
add a comment |
The issue is in the joining logic. The table customers is used as the driving table in the joins. But in the second join, you are using a derivative key column from the first join, to join with the third tables. This is resulting in a Cartesian output doubling the records from the result from the nth-1 join, which is leading to customer_invoices.total_price getting repeated twice, hence the rolled up value of this field is doubled.
At a high level I feel that the purpose of rolling up the prices is already achieved in SUM(customer_invoice_details.total_price).
But if you have a specific project requirement that SUM(customer_invoices.total_price) should also be obtained and must match with SUM(customer_invoice_details.total_price), then you can do this:
In a separate query, Join customer_invoice_details and customer_invoices. Roll up the pricing fields, and have a result such that you have only one record for one customer ID.
Then use this as a sub-query and join it with the customers table.
add a comment |
You are aggregating along multiple dimensions. This is challenging. I would suggest doing the aggregation along each dimension independently:
select c.id as customerID, c.last_name, c.first_name,
ci.invoice_total,
cid.details_total
from customers c join
(select ci.sum(ci.total_price) as invoice_total
from customer_invoices ci
group by ci.customer_id
) ci
on ci.customer_id = c.id join
(select ci.sum(cid.total_price) as details_total
from customer_invoices ci join
customer_invoice_details cid
on cid.customer_invoice_id = ci.id
group by ci.customer_id
) cid
on cid.customer_id = c.id
where c.id = 574413;
A faster version (for one customer) uses correlated subqueries:
select c.id as customerID, c.last_name, c.first_name,
(select ci.customer_id, sum(ci.total_price) as invoice_total
from customer_invoices ci
where ci.customer_id = c.id
) as invoice_total,
(select ci.customer_id, sum(cid.total_price) as details_total
from customer_invoices ci join
customer_invoice_details cid
on cid.customer_invoice_id = ci.id
where ci.customer_id = c.id
) as details_total
from customers c
where c.id = 574413;
I didn't quiet get what you are doing here, but there is this error :Unknown column 'customer_invoice_details.total_price' in 'field list'. I changedcustomer_invoice_detailstocidin theselectclause, but still the same errorUnknown column 'cid.total_price' in 'field list'
– dwix
Nov 15 '18 at 15:47
@dwix . . . Fixed.
– Gordon Linoff
Nov 15 '18 at 15:49
I see, the result is correct even though the query is a bit slow. I'm still trying to understand what you did : ). Thanks for the answer.
– dwix
Nov 15 '18 at 15:52
There is an error inwhere cid.customer_id = c.idthere is nocustomer_idincid.
– dwix
Nov 15 '18 at 15:59
1
@dwix . . . That was a typo.
– Gordon Linoff
Nov 15 '18 at 16:16
|
show 2 more comments
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53322414%2fusing-sum-with-joins-in-mysql-returns-unexpected-result%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
When you mix normal columns with aggregate functions (for example SUM), you need to use GROUP BY where you list the normal columns from the SELECT.
The reason for the excessive amount in total_price for invoices is that the SUM is also calculated over each detail row as it is part of the join. Use this:
select c.id as customerID,
c.last_name,
c.first_name,
SUM(ci.total_price) as invoice_total,
SUM((select SUM(d.total_price)
from customer_invoice_details d
where d.customer_invoice_id = ci.id)) as 'detail_total_price'
from customers c
join customer_invoices ci on ci.customer_id = c.id
where c.id = 574413
group by c.id, c.last_name, c.first_name
db-fiddle
I see, thank you, but your query still doesn't return the correct result. It returns two rows, the first withtotal_price: 250, and the second row withtotal_price: 700, instead of just one row oftotal_price: 950.
– dwix
Nov 15 '18 at 15:35
There was a typo in the code. Corrected.
– slaakso
Nov 15 '18 at 15:47
Changingci.idtoci.invoice_idwasn't the problem. because the column is actuallyid.
– dwix
Nov 15 '18 at 15:50
Forgot to sum the rows together. Done now.
– slaakso
Nov 15 '18 at 15:56
1
Actually, you do not need the outer query as you can do the SUM directly in the main query. Should be even (a bit) faster.
– slaakso
Nov 15 '18 at 16:40
|
show 1 more comment
When you mix normal columns with aggregate functions (for example SUM), you need to use GROUP BY where you list the normal columns from the SELECT.
The reason for the excessive amount in total_price for invoices is that the SUM is also calculated over each detail row as it is part of the join. Use this:
select c.id as customerID,
c.last_name,
c.first_name,
SUM(ci.total_price) as invoice_total,
SUM((select SUM(d.total_price)
from customer_invoice_details d
where d.customer_invoice_id = ci.id)) as 'detail_total_price'
from customers c
join customer_invoices ci on ci.customer_id = c.id
where c.id = 574413
group by c.id, c.last_name, c.first_name
db-fiddle
I see, thank you, but your query still doesn't return the correct result. It returns two rows, the first withtotal_price: 250, and the second row withtotal_price: 700, instead of just one row oftotal_price: 950.
– dwix
Nov 15 '18 at 15:35
There was a typo in the code. Corrected.
– slaakso
Nov 15 '18 at 15:47
Changingci.idtoci.invoice_idwasn't the problem. because the column is actuallyid.
– dwix
Nov 15 '18 at 15:50
Forgot to sum the rows together. Done now.
– slaakso
Nov 15 '18 at 15:56
1
Actually, you do not need the outer query as you can do the SUM directly in the main query. Should be even (a bit) faster.
– slaakso
Nov 15 '18 at 16:40
|
show 1 more comment
When you mix normal columns with aggregate functions (for example SUM), you need to use GROUP BY where you list the normal columns from the SELECT.
The reason for the excessive amount in total_price for invoices is that the SUM is also calculated over each detail row as it is part of the join. Use this:
select c.id as customerID,
c.last_name,
c.first_name,
SUM(ci.total_price) as invoice_total,
SUM((select SUM(d.total_price)
from customer_invoice_details d
where d.customer_invoice_id = ci.id)) as 'detail_total_price'
from customers c
join customer_invoices ci on ci.customer_id = c.id
where c.id = 574413
group by c.id, c.last_name, c.first_name
db-fiddle
When you mix normal columns with aggregate functions (for example SUM), you need to use GROUP BY where you list the normal columns from the SELECT.
The reason for the excessive amount in total_price for invoices is that the SUM is also calculated over each detail row as it is part of the join. Use this:
select c.id as customerID,
c.last_name,
c.first_name,
SUM(ci.total_price) as invoice_total,
SUM((select SUM(d.total_price)
from customer_invoice_details d
where d.customer_invoice_id = ci.id)) as 'detail_total_price'
from customers c
join customer_invoices ci on ci.customer_id = c.id
where c.id = 574413
group by c.id, c.last_name, c.first_name
db-fiddle
edited Nov 15 '18 at 16:36
answered Nov 15 '18 at 15:32
slaaksoslaakso
3,2191820
3,2191820
I see, thank you, but your query still doesn't return the correct result. It returns two rows, the first withtotal_price: 250, and the second row withtotal_price: 700, instead of just one row oftotal_price: 950.
– dwix
Nov 15 '18 at 15:35
There was a typo in the code. Corrected.
– slaakso
Nov 15 '18 at 15:47
Changingci.idtoci.invoice_idwasn't the problem. because the column is actuallyid.
– dwix
Nov 15 '18 at 15:50
Forgot to sum the rows together. Done now.
– slaakso
Nov 15 '18 at 15:56
1
Actually, you do not need the outer query as you can do the SUM directly in the main query. Should be even (a bit) faster.
– slaakso
Nov 15 '18 at 16:40
|
show 1 more comment
I see, thank you, but your query still doesn't return the correct result. It returns two rows, the first withtotal_price: 250, and the second row withtotal_price: 700, instead of just one row oftotal_price: 950.
– dwix
Nov 15 '18 at 15:35
There was a typo in the code. Corrected.
– slaakso
Nov 15 '18 at 15:47
Changingci.idtoci.invoice_idwasn't the problem. because the column is actuallyid.
– dwix
Nov 15 '18 at 15:50
Forgot to sum the rows together. Done now.
– slaakso
Nov 15 '18 at 15:56
1
Actually, you do not need the outer query as you can do the SUM directly in the main query. Should be even (a bit) faster.
– slaakso
Nov 15 '18 at 16:40
I see, thank you, but your query still doesn't return the correct result. It returns two rows, the first with
total_price: 250, and the second row with total_price: 700, instead of just one row of total_price: 950.– dwix
Nov 15 '18 at 15:35
I see, thank you, but your query still doesn't return the correct result. It returns two rows, the first with
total_price: 250, and the second row with total_price: 700, instead of just one row of total_price: 950.– dwix
Nov 15 '18 at 15:35
There was a typo in the code. Corrected.
– slaakso
Nov 15 '18 at 15:47
There was a typo in the code. Corrected.
– slaakso
Nov 15 '18 at 15:47
Changing
ci.id to ci.invoice_id wasn't the problem. because the column is actually id.– dwix
Nov 15 '18 at 15:50
Changing
ci.id to ci.invoice_id wasn't the problem. because the column is actually id.– dwix
Nov 15 '18 at 15:50
Forgot to sum the rows together. Done now.
– slaakso
Nov 15 '18 at 15:56
Forgot to sum the rows together. Done now.
– slaakso
Nov 15 '18 at 15:56
1
1
Actually, you do not need the outer query as you can do the SUM directly in the main query. Should be even (a bit) faster.
– slaakso
Nov 15 '18 at 16:40
Actually, you do not need the outer query as you can do the SUM directly in the main query. Should be even (a bit) faster.
– slaakso
Nov 15 '18 at 16:40
|
show 1 more comment
I used join against sub queries and then did a sum on the sums
SELECT c.id as customerID,
c.last_name,
c.first_name
SUM(i.sum) as invoice_total,
SUM(d.sum) AS details_total
FROM customers c
JOIN (SELECT id, customer_id, SUM(total_price) AS sum
FROM customer_invoices
GROUP BY id, customer_id) AS i ON i.customer_id = c.id
JOIN (SELECT customer_invoice_id as id, SUM(total_price) AS sum
FROM customer_invoice_details
GROUP BY customer_invoice_id) AS d ON d.id = i.id
WHERE c.id = 574413
GROUP BY c.id, c.name
add a comment |
I used join against sub queries and then did a sum on the sums
SELECT c.id as customerID,
c.last_name,
c.first_name
SUM(i.sum) as invoice_total,
SUM(d.sum) AS details_total
FROM customers c
JOIN (SELECT id, customer_id, SUM(total_price) AS sum
FROM customer_invoices
GROUP BY id, customer_id) AS i ON i.customer_id = c.id
JOIN (SELECT customer_invoice_id as id, SUM(total_price) AS sum
FROM customer_invoice_details
GROUP BY customer_invoice_id) AS d ON d.id = i.id
WHERE c.id = 574413
GROUP BY c.id, c.name
add a comment |
I used join against sub queries and then did a sum on the sums
SELECT c.id as customerID,
c.last_name,
c.first_name
SUM(i.sum) as invoice_total,
SUM(d.sum) AS details_total
FROM customers c
JOIN (SELECT id, customer_id, SUM(total_price) AS sum
FROM customer_invoices
GROUP BY id, customer_id) AS i ON i.customer_id = c.id
JOIN (SELECT customer_invoice_id as id, SUM(total_price) AS sum
FROM customer_invoice_details
GROUP BY customer_invoice_id) AS d ON d.id = i.id
WHERE c.id = 574413
GROUP BY c.id, c.name
I used join against sub queries and then did a sum on the sums
SELECT c.id as customerID,
c.last_name,
c.first_name
SUM(i.sum) as invoice_total,
SUM(d.sum) AS details_total
FROM customers c
JOIN (SELECT id, customer_id, SUM(total_price) AS sum
FROM customer_invoices
GROUP BY id, customer_id) AS i ON i.customer_id = c.id
JOIN (SELECT customer_invoice_id as id, SUM(total_price) AS sum
FROM customer_invoice_details
GROUP BY customer_invoice_id) AS d ON d.id = i.id
WHERE c.id = 574413
GROUP BY c.id, c.name
answered Nov 15 '18 at 15:47
Joakim DanielsonJoakim Danielson
10.9k3725
10.9k3725
add a comment |
add a comment |
The issue is in the joining logic. The table customers is used as the driving table in the joins. But in the second join, you are using a derivative key column from the first join, to join with the third tables. This is resulting in a Cartesian output doubling the records from the result from the nth-1 join, which is leading to customer_invoices.total_price getting repeated twice, hence the rolled up value of this field is doubled.
At a high level I feel that the purpose of rolling up the prices is already achieved in SUM(customer_invoice_details.total_price).
But if you have a specific project requirement that SUM(customer_invoices.total_price) should also be obtained and must match with SUM(customer_invoice_details.total_price), then you can do this:
In a separate query, Join customer_invoice_details and customer_invoices. Roll up the pricing fields, and have a result such that you have only one record for one customer ID.
Then use this as a sub-query and join it with the customers table.
add a comment |
The issue is in the joining logic. The table customers is used as the driving table in the joins. But in the second join, you are using a derivative key column from the first join, to join with the third tables. This is resulting in a Cartesian output doubling the records from the result from the nth-1 join, which is leading to customer_invoices.total_price getting repeated twice, hence the rolled up value of this field is doubled.
At a high level I feel that the purpose of rolling up the prices is already achieved in SUM(customer_invoice_details.total_price).
But if you have a specific project requirement that SUM(customer_invoices.total_price) should also be obtained and must match with SUM(customer_invoice_details.total_price), then you can do this:
In a separate query, Join customer_invoice_details and customer_invoices. Roll up the pricing fields, and have a result such that you have only one record for one customer ID.
Then use this as a sub-query and join it with the customers table.
add a comment |
The issue is in the joining logic. The table customers is used as the driving table in the joins. But in the second join, you are using a derivative key column from the first join, to join with the third tables. This is resulting in a Cartesian output doubling the records from the result from the nth-1 join, which is leading to customer_invoices.total_price getting repeated twice, hence the rolled up value of this field is doubled.
At a high level I feel that the purpose of rolling up the prices is already achieved in SUM(customer_invoice_details.total_price).
But if you have a specific project requirement that SUM(customer_invoices.total_price) should also be obtained and must match with SUM(customer_invoice_details.total_price), then you can do this:
In a separate query, Join customer_invoice_details and customer_invoices. Roll up the pricing fields, and have a result such that you have only one record for one customer ID.
Then use this as a sub-query and join it with the customers table.
The issue is in the joining logic. The table customers is used as the driving table in the joins. But in the second join, you are using a derivative key column from the first join, to join with the third tables. This is resulting in a Cartesian output doubling the records from the result from the nth-1 join, which is leading to customer_invoices.total_price getting repeated twice, hence the rolled up value of this field is doubled.
At a high level I feel that the purpose of rolling up the prices is already achieved in SUM(customer_invoice_details.total_price).
But if you have a specific project requirement that SUM(customer_invoices.total_price) should also be obtained and must match with SUM(customer_invoice_details.total_price), then you can do this:
In a separate query, Join customer_invoice_details and customer_invoices. Roll up the pricing fields, and have a result such that you have only one record for one customer ID.
Then use this as a sub-query and join it with the customers table.
answered Nov 15 '18 at 15:52
JonathanJonathan
77110
77110
add a comment |
add a comment |
You are aggregating along multiple dimensions. This is challenging. I would suggest doing the aggregation along each dimension independently:
select c.id as customerID, c.last_name, c.first_name,
ci.invoice_total,
cid.details_total
from customers c join
(select ci.sum(ci.total_price) as invoice_total
from customer_invoices ci
group by ci.customer_id
) ci
on ci.customer_id = c.id join
(select ci.sum(cid.total_price) as details_total
from customer_invoices ci join
customer_invoice_details cid
on cid.customer_invoice_id = ci.id
group by ci.customer_id
) cid
on cid.customer_id = c.id
where c.id = 574413;
A faster version (for one customer) uses correlated subqueries:
select c.id as customerID, c.last_name, c.first_name,
(select ci.customer_id, sum(ci.total_price) as invoice_total
from customer_invoices ci
where ci.customer_id = c.id
) as invoice_total,
(select ci.customer_id, sum(cid.total_price) as details_total
from customer_invoices ci join
customer_invoice_details cid
on cid.customer_invoice_id = ci.id
where ci.customer_id = c.id
) as details_total
from customers c
where c.id = 574413;
I didn't quiet get what you are doing here, but there is this error :Unknown column 'customer_invoice_details.total_price' in 'field list'. I changedcustomer_invoice_detailstocidin theselectclause, but still the same errorUnknown column 'cid.total_price' in 'field list'
– dwix
Nov 15 '18 at 15:47
@dwix . . . Fixed.
– Gordon Linoff
Nov 15 '18 at 15:49
I see, the result is correct even though the query is a bit slow. I'm still trying to understand what you did : ). Thanks for the answer.
– dwix
Nov 15 '18 at 15:52
There is an error inwhere cid.customer_id = c.idthere is nocustomer_idincid.
– dwix
Nov 15 '18 at 15:59
1
@dwix . . . That was a typo.
– Gordon Linoff
Nov 15 '18 at 16:16
|
show 2 more comments
You are aggregating along multiple dimensions. This is challenging. I would suggest doing the aggregation along each dimension independently:
select c.id as customerID, c.last_name, c.first_name,
ci.invoice_total,
cid.details_total
from customers c join
(select ci.sum(ci.total_price) as invoice_total
from customer_invoices ci
group by ci.customer_id
) ci
on ci.customer_id = c.id join
(select ci.sum(cid.total_price) as details_total
from customer_invoices ci join
customer_invoice_details cid
on cid.customer_invoice_id = ci.id
group by ci.customer_id
) cid
on cid.customer_id = c.id
where c.id = 574413;
A faster version (for one customer) uses correlated subqueries:
select c.id as customerID, c.last_name, c.first_name,
(select ci.customer_id, sum(ci.total_price) as invoice_total
from customer_invoices ci
where ci.customer_id = c.id
) as invoice_total,
(select ci.customer_id, sum(cid.total_price) as details_total
from customer_invoices ci join
customer_invoice_details cid
on cid.customer_invoice_id = ci.id
where ci.customer_id = c.id
) as details_total
from customers c
where c.id = 574413;
I didn't quiet get what you are doing here, but there is this error :Unknown column 'customer_invoice_details.total_price' in 'field list'. I changedcustomer_invoice_detailstocidin theselectclause, but still the same errorUnknown column 'cid.total_price' in 'field list'
– dwix
Nov 15 '18 at 15:47
@dwix . . . Fixed.
– Gordon Linoff
Nov 15 '18 at 15:49
I see, the result is correct even though the query is a bit slow. I'm still trying to understand what you did : ). Thanks for the answer.
– dwix
Nov 15 '18 at 15:52
There is an error inwhere cid.customer_id = c.idthere is nocustomer_idincid.
– dwix
Nov 15 '18 at 15:59
1
@dwix . . . That was a typo.
– Gordon Linoff
Nov 15 '18 at 16:16
|
show 2 more comments
You are aggregating along multiple dimensions. This is challenging. I would suggest doing the aggregation along each dimension independently:
select c.id as customerID, c.last_name, c.first_name,
ci.invoice_total,
cid.details_total
from customers c join
(select ci.sum(ci.total_price) as invoice_total
from customer_invoices ci
group by ci.customer_id
) ci
on ci.customer_id = c.id join
(select ci.sum(cid.total_price) as details_total
from customer_invoices ci join
customer_invoice_details cid
on cid.customer_invoice_id = ci.id
group by ci.customer_id
) cid
on cid.customer_id = c.id
where c.id = 574413;
A faster version (for one customer) uses correlated subqueries:
select c.id as customerID, c.last_name, c.first_name,
(select ci.customer_id, sum(ci.total_price) as invoice_total
from customer_invoices ci
where ci.customer_id = c.id
) as invoice_total,
(select ci.customer_id, sum(cid.total_price) as details_total
from customer_invoices ci join
customer_invoice_details cid
on cid.customer_invoice_id = ci.id
where ci.customer_id = c.id
) as details_total
from customers c
where c.id = 574413;
You are aggregating along multiple dimensions. This is challenging. I would suggest doing the aggregation along each dimension independently:
select c.id as customerID, c.last_name, c.first_name,
ci.invoice_total,
cid.details_total
from customers c join
(select ci.sum(ci.total_price) as invoice_total
from customer_invoices ci
group by ci.customer_id
) ci
on ci.customer_id = c.id join
(select ci.sum(cid.total_price) as details_total
from customer_invoices ci join
customer_invoice_details cid
on cid.customer_invoice_id = ci.id
group by ci.customer_id
) cid
on cid.customer_id = c.id
where c.id = 574413;
A faster version (for one customer) uses correlated subqueries:
select c.id as customerID, c.last_name, c.first_name,
(select ci.customer_id, sum(ci.total_price) as invoice_total
from customer_invoices ci
where ci.customer_id = c.id
) as invoice_total,
(select ci.customer_id, sum(cid.total_price) as details_total
from customer_invoices ci join
customer_invoice_details cid
on cid.customer_invoice_id = ci.id
where ci.customer_id = c.id
) as details_total
from customers c
where c.id = 574413;
edited Nov 15 '18 at 20:33
answered Nov 15 '18 at 15:43
Gordon LinoffGordon Linoff
799k37320426
799k37320426
I didn't quiet get what you are doing here, but there is this error :Unknown column 'customer_invoice_details.total_price' in 'field list'. I changedcustomer_invoice_detailstocidin theselectclause, but still the same errorUnknown column 'cid.total_price' in 'field list'
– dwix
Nov 15 '18 at 15:47
@dwix . . . Fixed.
– Gordon Linoff
Nov 15 '18 at 15:49
I see, the result is correct even though the query is a bit slow. I'm still trying to understand what you did : ). Thanks for the answer.
– dwix
Nov 15 '18 at 15:52
There is an error inwhere cid.customer_id = c.idthere is nocustomer_idincid.
– dwix
Nov 15 '18 at 15:59
1
@dwix . . . That was a typo.
– Gordon Linoff
Nov 15 '18 at 16:16
|
show 2 more comments
I didn't quiet get what you are doing here, but there is this error :Unknown column 'customer_invoice_details.total_price' in 'field list'. I changedcustomer_invoice_detailstocidin theselectclause, but still the same errorUnknown column 'cid.total_price' in 'field list'
– dwix
Nov 15 '18 at 15:47
@dwix . . . Fixed.
– Gordon Linoff
Nov 15 '18 at 15:49
I see, the result is correct even though the query is a bit slow. I'm still trying to understand what you did : ). Thanks for the answer.
– dwix
Nov 15 '18 at 15:52
There is an error inwhere cid.customer_id = c.idthere is nocustomer_idincid.
– dwix
Nov 15 '18 at 15:59
1
@dwix . . . That was a typo.
– Gordon Linoff
Nov 15 '18 at 16:16
I didn't quiet get what you are doing here, but there is this error :
Unknown column 'customer_invoice_details.total_price' in 'field list'. I changed customer_invoice_details to cid in the select clause, but still the same error Unknown column 'cid.total_price' in 'field list'– dwix
Nov 15 '18 at 15:47
I didn't quiet get what you are doing here, but there is this error :
Unknown column 'customer_invoice_details.total_price' in 'field list'. I changed customer_invoice_details to cid in the select clause, but still the same error Unknown column 'cid.total_price' in 'field list'– dwix
Nov 15 '18 at 15:47
@dwix . . . Fixed.
– Gordon Linoff
Nov 15 '18 at 15:49
@dwix . . . Fixed.
– Gordon Linoff
Nov 15 '18 at 15:49
I see, the result is correct even though the query is a bit slow. I'm still trying to understand what you did : ). Thanks for the answer.
– dwix
Nov 15 '18 at 15:52
I see, the result is correct even though the query is a bit slow. I'm still trying to understand what you did : ). Thanks for the answer.
– dwix
Nov 15 '18 at 15:52
There is an error in
where cid.customer_id = c.id there is no customer_id in cid.– dwix
Nov 15 '18 at 15:59
There is an error in
where cid.customer_id = c.id there is no customer_id in cid.– dwix
Nov 15 '18 at 15:59
1
1
@dwix . . . That was a typo.
– Gordon Linoff
Nov 15 '18 at 16:16
@dwix . . . That was a typo.
– Gordon Linoff
Nov 15 '18 at 16:16
|
show 2 more comments
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53322414%2fusing-sum-with-joins-in-mysql-returns-unexpected-result%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
Your joins are creating multiple records (one for each detail), you will have a total of 950.00 in both of these detail records and since there are 2 rows they are being summed together. You need to include a GROUP BY to your query and this should yield the results you're looking for.
– haag1
Nov 15 '18 at 15:23