Reputation: 5770
I have a foo table which has a one-to-many relationship with the BAR table. FOO also has a many-to-many relationship with QUX.
To illustrate:
FOO
+--------+
| fid |
+--------+
| 1 |
| 2 |
| 3 |
| 4 |
+--------+
BAR
+------+-------+-----+
| bid | cost | fid |
+------+-------+-----+
| 1 | 2 | 1 |
| 2 | 4 | 1 |
| 3 | 8 | 2 |
| 4 | 42 | 3 |
| 5 | 21 | 3 |
| 6 | 5 | 4 |
| 7 | 98 | 2 |
| 8 | 30 | 4 |
+------+-------+-----+
FOOQUX
+------+------+
| fid | qid |
+------+------+
| 1 | 2 |
| 2 | 1 |
| 2 | 3 |
| 4 | 1 |
+------+------+
QUX
+------+
| qid |
+------+
| 1 |
| 2 |
| 3 |
| 4 |
+------+
Now I want to calculate the sum of BAR.cost for every FOO entry, but I want to filter by QUX in terms of "FOO has an association with any element of QUX"
I tried using this sentence:
SELECT fid, sum(cost)
FROM FOO
INNER JOIN BAR on BAR.fid = FOO.fid
LEFT JOIN FOOQUX ON FOOQUX.fid = FOO.fid
But this returns an entry for each instance of FOO in FOOQUX, so in the case of fid=2 (which has two QUX associated to it) we'll have double the amount of cost than in reality.
Maybe this is a simple problem but I'm struggling on how to solve it.
Upvotes: 0
Views: 1216
Reputation:
I think this will help You. Group by foo.fid will guarantee that every foo records will appear only once with the sum of its bar-costs. Having
filters the aggregated records: a record will returned only if the FOOQUX table contains its fid
.
SELECT fid, SUM(cost)
FROM foo JOIN bar on bar.fid=foo.fid
GROUP BY foo.fid
HAVING foo.fid IN (SELECT fid FROM FOOQUX)
Upvotes: 1