Reputation: 2337
I have the following SQL:
SELECT
t.amount
FROM
transactions t
JOIN contracts c ON t.contractId = c.id
JOIN insertions i ON c.id = i.contractId
JOIN magazines m ON i.magazineId = m.id
WHERE m.id = 26
AND t.isChargedBack IS FALSE
AND t.`timestamp` >= '2013-09-12'
AND t.`timestamp` <= date_add('2013-09-12',interval 1 month)
GROUP BY
t.id;
Which yields:
1100
800
1025
500
1200
552
395
395
1170
1000
675
I want only the SUM of this result. I expect 8812.
So I use the following SQL:
SELECT
IFNULL(SUM(t.amount),0)
FROM
transactions t
JOIN contracts c ON t.contractId = c.id
JOIN insertions i ON c.id = i.contractId
JOIN magazines m ON i.magazineId = m.id
WHERE m.id = 26
AND t.isChargedBack IS FALSE
AND t.`timestamp` >= '2013-09-12'
AND t.`timestamp` <= date_add('2013-09-12',interval 1 month)
GROUP BY
t.id;
And this is my result:
39600
9600
61500
9000
43200
49680
14220
5925
7020
36000
72900
????
Upvotes: 0
Views: 82
Reputation: 1269513
You have a problem with your original query. It is not doing what you think it is doing. You are aggregating by t.id
, but selecting t.amount
. That means that MySQL is choosing an arbitrary value.
Why is this happening? One possibility is that the following is the right amount for each transaction:
SELECT sum(t.amount)
FROM transactions t
JOIN contracts c ON t.contractId = c.id
JOIN insertions i ON c.id = i.contractId
JOIN magazines m ON i.magazineId = m.id
WHERE m.id = 26
AND t.isChargedBack IS FALSE
AND t.`timestamp` >= '2013-09-12'
AND t.`timestamp` <= date_add('2013-09-12',interval 1 month)
GROUP BY t.id;
If so, just removing the group by
will give the right total.
Another possibility is that the join
s are multiplying the rows. My suspicion would be insertions
. If that is the case, then t.amount
is being repeated and the query you want would choose just one value:
SELECT min(t.amount)
FROM transactions t
JOIN contracts c ON t.contractId = c.id
JOIN insertions i ON c.id = i.contractId
JOIN magazines m ON i.magazineId = m.id
WHERE m.id = 26
AND t.isChargedBack IS FALSE
AND t.`timestamp` >= '2013-09-12'
AND t.`timestamp` <= date_add('2013-09-12',interval 1 month)
GROUP BY t.id;
If this is the problem, then to get the full sum, you can use a sub-query:
select sum(amount)
from (SELECT min(t.amount) as amount
FROM transactions t
JOIN contracts c ON t.contractId = c.id
JOIN insertions i ON c.id = i.contractId
JOIN magazines m ON i.magazineId = m.id
WHERE m.id = 26
AND t.isChargedBack IS FALSE
AND t.`timestamp` >= '2013-09-12'
AND t.`timestamp` <= date_add('2013-09-12',interval 1 month)
GROUP BY t.id
) t
Upvotes: 1