2010-11-24 107 views
0

我有两个名为'events'和'topics'的表,每个表可以有很多注释。PHP&Mysql - 两个表之间的左外连接

我需要做的是列出所有事件和主题与每行的评论量。我设法返回所有主题,这很好,但我不知道如何将事件表添加到MySql。下面列出了评论和事件表字段。任何人都可以用这个查询来帮我吗?

活动:

  • ID
  • EVENT_NAME

评论:

  • POST_ID < - 对于任何一个事件或主题表
  • 表中的相关型号ID < - 该行属于这样无论是主题或事件

    SELECT 
        t.id, t.title, c.created_at, 
        IF(ISNULL(c.allComments), 0, c.allComments) AS totalComments 
    FROM topics AS t 
    LEFT OUTER JOIN (
        SELECT created_at, post_id, COUNT(*) AS allComments 
        FROM comments 
        GROUP BY post_id 
    ) AS c ON c.post_id = t.id 
    ORDER BY tc.created_at DESC, c.allComments DESC 
    
+1

这是一个[多态协会(http://stackoverflow.com/tags/polymorphic-associations的例子/ hot),这被认为是SQL反模式(参见[Bill Karwin的书:SQL Antipatterns](http://www.pragprog.com/titles/bksqla/sql-antipatterns)以获得更多信息),我建议重新设计表格模式... – ircmaxell 2010-11-24 15:11:36

回答

1

听起来事件和主题应该是同一个表。

不过,我想我们可以用UNION来做到这一点。活动和主题有我希望的相同专栏? (或至少是同样重要的?)

(SELECT c.table as event_or_topic, e.*, count(C.table), MAX(C.created_at) as latest_c 
FROM events E LEFT JOIN comments C on (C.post_id = E.id) 
WHERE C.table = 'Events' 
GROUP BY C.post_id) 
UNION 
(SELECT c.table as event_or_topic, t.id*, count(C.table), MAX(C.created_at) as latest_c 
FROM topics T LEFT JOIN comments C on (C.post_id = E.id) 
WHERE C.table = 'Topics' 
GROUP BY C.post_id) 
ORDER BY latest_c 

请注意,ORDER BY适用于整个UNION,而不是单独的SELECT。

使用LEFT JOIN应该允许没有评论的那些行仍然显示。我认为问题在于我们的部分选择依赖于评论(即--Ctable,在最后的评论中排序等)。计数应该没问题 - 如果没有任何评论,只会为零。

您可能需要稍微更改SELECT部分​​。我想显示C.table,以便知道某行是否是主题或事件,但恐怕可能会使计数错误。除了伯爵之外,你还需要评论吗?您在查询中使用了post_id和table之外的其他列,而您忽略了在您的问题中进行解释。

你还有列,我不知道它们是什么,就像评论的zoneTable

+0

嗨,感谢您的帮助,我需要它也显示事件和主题表中的所有内容,目前它只显示一个事件或主题,如果它有评论。另外我需要通过最新的评论 - C.created_at来订购它。想知道如何将它添加进去吗? – Peter 2010-11-24 16:10:09

0

试试这个表:

SELECT t.id, t.title, c.created_at, COUNT(c.allComments) AS totalComments FROM topics AS t LEFT JOIN comments c ON t.id=c.post_id GROUP BY t.id ORDER BY tc.created_at DESC, c.allComments DESC

0

如果我理解你的问题,你有3个表:

-Events

-Topics

- 评论

如果这是真的这样的事情应该提取所有的数据:

SELECT * 
FROM events,topics 
LEFT JOIN comments ON post_ID = ID 
ORDER BY date DESC 

希望我沿着正确的路线!

W.

0

我有它的工作。如果任何人这样做的更好的和有效的方式知道,那么请让我知道:

(SELECT t.id, t.title, tc.dateCreated AS commentDate, 
IF(ISNULL(tc.allComments), 0, tc.allComments) AS totalComments, 
t.LastActive as dateChanged 
    FROM Events AS t 
    LEFT OUTER JOIN (
      SELECT MAX(created_at) AS dateCreated, post_id, 
      COUNT(*) AS allComments 
      FROM comments 
      GROUP BY post_id 
     ) AS tc ON tc.post_id = t.id) 
UNION 
(SELECT t.id, t.title, tc.dateCreated AS commentDate, 
IF(ISNULL(tc.allComments), 0, tc.allComments) AS totalComments, 
t.LastActive as dateChanged 
    FROM topics AS t 
    LEFT OUTER JOIN (
      SELECT MAX(created_at) AS dateCreated, post_id, 
      COUNT(*) AS allComments 
      FROM comments 
      GROUP BY post_id 
     ) AS tc ON tc.post_id = t.id) 
ORDER BY commentDate DESC, dateChanged DESC, totalComments DESC