MySQL中的连接和计数问题

时间:2013-09-23 23:33:53

标签: mysql sql join

我对这个MySQL选择查询感到困惑,我得到了正确的信息,除了COUNT(messages)COUNT(project_ideas)回来的次数是两倍。

SELECT  
    create_project.title, 
    image1, 
    create_project.description, 
    create_project.date, 
    create_project.active, 
    create_project.completed, 
    create_project.project_id, 
    categories.name,
    messages.receiver_read, 
    project_ideas.project_id,
    COUNT(messages.ideas_id) AS num_of_messages,
    COUNT(project_ideas.ideas_id) AS num_of_ideas
FROM 
    create_project
    LEFT JOIN project_ideas ON create_project.project_id = project_ideas.project_id
    LEFT JOIN messages ON messages.project_id = create_project.project_id
    JOIN categories ON create_project.category = categories.category_id 
WHERE 
    create_project.user_id = {$_SESSION['user']['user_id']} 
    AND create_project.active = 1 
    AND create_project.completed = 1
GROUP BY project_ideas.project_id
ORDER BY create_project.date ASC

感谢任何帮助。

2 个答案:

答案 0 :(得分:-1)

试试这个:

COUNT(messages.ideas_id) OVER(PARTITION BY  messages.project_id)  AS num_of_messages,
COUNT(project_ideas.ideas_id) OVER(PARTITION BY  project_ideas.project_id) AS num_of_ideas

答案 1 :(得分:-1)

如果create_project表格中有多行与messages表格中的单行匹配,那么messages中的行将针对每个匹配的行显示一次在create_project。此外,由于您有许多联接,因此可以显示许多重复行的位置。例如,如果项目属于多个类别,则对categories的联接将导致其他表中的每一行都被复制为项目所属的每个类别。我打赌这实际上是你错误的根源。使它如此阴险的原因是GROUP BY隐藏了重复的地方,除了计算和求和的函数。

@ Wrikken的评论是正确和有用的。如果您删除GROUP BY,则会看到计数中包含的每一行。在那里,您应该看到messages表中的行重复出现。正如@Wrikken所说,您可以使用COUNT(DISTINCT ...)来缓解这种情况。但是,在使用COUNT(DISTINCT ...)填写问题之前,我会尝试确保您的联接正确或表格数据是否正确。也就是说,确保COUNT(DISTINCT ...)在您正在寻找的数据方面确实具有逻辑意义。

与你的行动问题无关,我不得不指出我看到的东西(并且在我知道更好之前已经完成了自己)。虽然MySQL允许您在选择列表中包含不在GROUP BY或聚合函数(例如COUNT())中的列,但这样做是不好的做法。结果在技术上未定义(参见:http://dev.mysql.com/doc/refman/5.0/en/group-by-extensions.html)。我认为MySQL做错了,但这不是我的号召。其他数据库系统会将此标记为错误。