2013-09-01 61 views
2

我有一个SUM(value)计算每个idea的投票,但是这受到每个想法可以具有的数量tag的影响。MySQL组通过影响其他组

例如,

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 

因此,如果有一个以上的tags.name,那么SUM()得到通过的tags.name

我怎样才能解决这个数乘以?

+0

每隔DBMS会拒绝这种说法。阅读http://rpbouman.blogspot.de/2007/05/debunking-group-by-myths.html和http://www.mysqlperformanceblog.com/2006/09/06/wrong-group-by-makes -your-queries-fragile /了解你的'group by'用法有什么问题。 –

回答

1

如果你不想让你的SUM患有tags,你不应该包括tags到您的SUM查询。

我认为你可以将你的查询分成2部分(查询在查询内)。首先总结没有的想法,然后再加入的想法,结果基本数据的第一部分

东西想(抱歉,我没测试我的查询还没有,但这个想法是这样的):

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 

希望这有助于

+0

谢谢!使用子查询得到它='' – ahren

1
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 

SQLFIDDLE

编辑:

随着标签数包括在结果列:

Results

| 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 | 
+0

可能是'* t2.cnt'不是你想要的地方:) –

+0

你的投票仍然乘以标签的数量。例如,在你的'idea.id = 3'中,你只有一个'-1'投票,但是数据显示'-16' – ahren

+0

可能是我的测试数据或者你的逻辑的另一部分,但是看看这个[SQLFIDDLE](http://www.sqlfiddle.com/#!2/e02df1/16/0),你会看到'* t2.cnt'包含正确数量的标签。因此,只需添加'LEFT JOIN(SELECT idea_id,COUNT(*)AS cnt FROM tags_rel GROUP BY tags_rel.idea_id)t2 ON ideas.id = t2.idea_id'并在需要的地方添加* t2.cnt'在你自己的代码 –