Reputation: 5670
I have a forum site with posts (gems) and file attachments (gemdetail) along with replies (gems) to the posts and the replies can also have file attachments (gemdetail). Since both posts and replies are stored in the same table, it makes for an interesting left join which selects all posts with associated replies and detail.
I want to add another table to the mix (rating) which allows the user to rate each post. I then want to be able in the same query to get the sum total rating for each post. How to add sum(rating) so each row of the output will have the sum for the gemid. I know I need a sum sub-query (derived table w/ ad-hoc result sets) similar to the one found here, but it is above my skill set. Thanks in advance.
The table structure is as follows
table: gems
gemid title replygemid
----- ----- ----------
220 map NULL
223 inhabitants NULL
403 reply to map 220
table: gemdetail
gemid filename
------ --------
220 uganda-map.jpg
220 mozambique-map.jpg
223 uganda-inhabitants.jpg
223 kenya-inhabitants.jpg
403 mona-lisa-x8.jpg
table: rating (to be added)
gemid rating
----- -------
220 1
220 5
223 3
403 -1
My current (simplified) query
SELECT g.gemid as ggemid, g.title as gtitle, gemdetail.filename as gfilename, r.filename as rfilename
FROM (SELECT gems.* FROM gems ) g
LEFT JOIN
(SELECT title, x.gemid, x.replygemid, x.userid, y.filename from gems x
LEFT JOIN gemdetail y ON x.gemid = y.gemid ) r ON g.gemid = r.replygemid
LEFT JOIN gemdetail ON g.gemid = gemdetail.gemid
Results may look like this
ggemid replygemid gtitle gfilename rfilename
------ ---------- ------ --------------------- ----------------
220 403 Map uganda-map.jpg mona-lisa-x8.jpg
220 403 Map mozambique-map.jpg mona-lisa-x8.jpg
223 NULL Inhabitants uganda-inhabitants.jpg NULL
223 NULL Inhabitants kenya-inhabitants.jpg NULL
223 NULL Inhabitants kenya-inhabitants.jpg NULL
Upvotes: 1
Views: 1276
Reputation: 5050
Query:
SELECT g.gemid as ggemid, g2.gemid as replygemid,
g.title as gtitle, gd.filename as gfilename,
gd2.filename as rfilename, SUM(rating) as rating
FROM gems g
INNER JOIN gemdetail gd ON g.gemid = gd.gemid
INNER JOIN rating r ON g.gemid = r.gemid
LEFT OUTER JOIN gems g2 ON g.gemid = g2.replygemid
LEFT OUTER JOIN gemdetail gd2 ON g2.gemid = gd2.gemid
GROUP BY g.gemid, g2.gemid, g.title,
gd.filename, gd2.filename
| GGEMID | REPLYGEMID | GTITLE | GFILENAME | RFILENAME | RATING |
|--------|------------|--------------|------------------------|------------------|--------|
| 220 | 403 | map | mozambique-map.jpg | mona-lisa-x8.jpg | 6 |
| 220 | 403 | map | uganda-map.jpg | mona-lisa-x8.jpg | 6 |
| 223 | (null) | inhabitants | kenya-inhabitants.jpg | (null) | 3 |
| 223 | (null) | inhabitants | uganda-inhabitants.jpg | (null) | 3 |
| 403 | (null) | reply to map | mona-lisa-x8.jpg | (null) | -1 |
Upvotes: 1
Reputation: 10411
I think this is what you want:
SELECT g.gemid as ggemid, g.title as gtitle, gemdetail.filename as gfilename, r.filename as rfilename, rt.sum_rating
FROM (SELECT gems.* FROM gems ) g
LEFT JOIN
(SELECT title, x.gemid, x.replygemid, x.userid, y.filename from gems x
LEFT JOIN gemdetail y ON x.gemid = y.gemid ) r ON g.gemid = r.replygemid
LEFT JOIN gemdetail ON g.gemid = gemdetail.gemid
LEFT JOIN (SELECT gemid, SUM(rating) as sum_rating from rating GROUP BY gemid) rt ON g.gemid = rt.gemid
Upvotes: 1