Reputation: 16961
I've got a SUM(value)
which calculates the votes for each idea
, but this gets affected by the amount of tag
s each idea can have.
For example,
SELECT
id,
title,
description,
COALESCE(SUM(case when value > 0 then value end),0) votes_up,
COALESCE(SUM(case when value < 0 then value end),0) votes_down,
GROUP_CONCAT(DISTINCT tags.name) AS 'tags',
FROM ideas
LEFT JOIN votes ON ideas.id = votes.idea_id
LEFT JOIN tags_rel ON ideas.id = tags_rel.idea_id
LEFT JOIN tags ON tags_rel.tag_id = tags.id
GROUP BY ideas.id
So if there are more than one tags.name
, then the SUM()
gets multiplied by the number of tags.name
How can I fix this?
Upvotes: 2
Views: 58
Reputation: 5050
SELECT
ideas.id,
title,
description,
COALESCE(SUM(case when value > 0 then value end),0)*t2.cnt votes_up,
COALESCE(SUM(case when value < 0 then value end),0)*t2.cnt votes_down,
GROUP_CONCAT(DISTINCT tags.name) AS 'tags'
FROM ideas
LEFT JOIN votes ON ideas.id = votes.idea_id
LEFT JOIN tags_rel ON ideas.id = tags_rel.idea_id
LEFT JOIN tags ON tags_rel.tag_id = tags.id
LEFT JOIN (SELECT idea_id, COUNT(*) AS cnt
FROM tags_rel
GROUP BY tags_rel.idea_id) t2 ON ideas.id = t2.idea_id
GROUP BY ideas.id
See SQLFIDDLE
EDIT :
With the tags count column included in the result :
| ID | TITLE | DESCRIPTION | VOTES_UP | VOTES_DOWN | TAGS | TAGS_COUNT |
|----|--------|-------------|----------|------------|-------------------------|------------|
| 1 | TITLE1 | DESC1 | 12 | -4 | tags1,tags2 | 2 |
| 2 | TITLE2 | DESC2 | 18 | 0 | tags4,tags5,tags3 | 3 |
| 3 | TITLE3 | DESC3 | 0 | -16 | tags9,tags7,tags8,tags6 | 4 |
| 4 | TITLE4 | DESC4 | 1 | 0 | tags10 | 1 |
Upvotes: 1
Reputation: 1539
If you don't want your SUM
affected with tags
, you should not include tags
into your SUM
query.
I think you can split your query into 2 part (query inside a query) . First to SUM without ideas , then JOIN ideas data for result base on first part
Something would like (sorry but I did not test my query yet but the idea is like that):
SELECT
t.id,
t.title,
t.description,
t.votes_up,
t.votes_down,
GROUP_CONCAT(DISTINCT tags.name) AS 'tags',
FROM
(
SELECT
id,
title,
description,
COALESCE(SUM(case when value > 0 then value end),0) votes_up,
COALESCE(SUM(case when value < 0 then value end),0) votes_down,
FROM ideas
LEFT JOIN votes ON ideas.id = votes.idea_id
GROUP BY ideas.id
) as t
LEFT JOIN tags_rel ON t.id = tags_rel.idea_id
LEFT JOIN tags ON tags_rel.tag_id = tags.id
Hope this help
Upvotes: 1