2013-09-23 41 views
0

我对这个MySQL select查询感到困惑,除了COUNT(messages)COUNT(project_ideas)回来两次之外,我收到了正确的信息。MySQL中的联接和计数问题

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 

任何帮助,将不胜感激谢谢。

+0

如果您忽略了GROUP BY,您可以看到原因。你最好的选择是'COUNT(DISTINCT messaged.some_uniqe_column_of_messages)',可能是主键... – Wrikken

+0

我还看到一个SQL注入漏洞。将准备好的语句与PDO一起使用,而不是将变量的值直接放入SQL中。即使你认为会话变量很干净,你仍然在掷骰子。 – siride

回答

-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这样做是错误的,但这不是我的呼叫。其他数据库系统会将此标记为错误。

+0

Downvoter谨慎解释? – siride

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

阅读标签和标题。 MySQL没有窗口函数。 – siride

+1

今天我第二次在MySQL上烧了。对于那个很抱歉。 – AlexG