SQL - 带修订历史记录的注释系统

时间:2013-01-31 20:42:49

标签: mysql sql database-design

我有两个表用于在MySQL数据库上存储注释。

第一个存储评论ID,发布的页面,编写评论的人,以及是否是对另一个评论的回复(分别如下)。

Comments
---------------------------------
CommentId    BIGINT      PK,NN,AI
OwnerId      BIGINT      
AuthorId     BIGINT      
ParentId     BIGINT      
Created      TIMESTAMP   

第二个存储评论的内容。

CommentsContent
----------------------------------
ContentId    BIGINT      PK,NN,AI
CommentId    BIGINT      
Content      TEXT        
Created      TIMESTAMP   

所以,让我们说Comments有以下记录:

CommentId  OwnerId  AuthorId  ParentId  Created
-----------------------------------------------------------
        1        1         2         0  2013-01-31 01:23:45
        2        1         2         0  2013-01-31 01:23:45

CommentsContent包含以下记录,显示评论的修改历史记录:

ContentId  CommentId  Content           Created
-----------------------------------------------------------
        1          1  Testing           2013-01-31 01:23:45
        2          2  Another test      2013-01-31 01:23:45
        3          1  Testing1          2013-01-31 01:23:46
        4          1  Testing123        2013-01-31 01:23:47

现在,我想获取最新评论以及它的上次更新日期(Created中的CommentsContent列)。

我试过了:

SELECT
    c.CommentId,
    c.AuthorId,
    c.ParentId,
    c.Created,
    cc.Created as Updated,
    cc.Content
FROM
    Comments as c
JOIN
    CommentsContent as cc
ON
    cc.CommentId = c.CommentId
WHERE
    c.OwnerId = 1

不幸的是,这会返回CommentsContentComments数据前面的所有行。

我正在寻找以下输出:

 CommentId  AuthorId  ParentId  Created              Updated              Content
 -------------------------------------------------------------------------------------
         1         2         0  2013-01-31 01:23:45  2013-01-31 01:23:47  Testing123
         2         2         0  2013-01-31 01:23:45  2013-01-31 01:23:45  Another test

这可以在单个查询中实现,而无需嵌入嵌套的SELECT。我需要使用GROUP条款吗?我听说GROUP条款表现不佳。我应该创建一些额外的索引来帮助加速GROUP条款吗?

感谢您的投入!

1 个答案:

答案 0 :(得分:1)

不幸的是,MySQL没有像SQL Server和其他一些窗口函数。因此,您需要使用子查询:

SELECT
    c.CommentId,
    c.AuthorId,
    c.ParentId,
    c.Created,
    cc.Created as Updated,
    cc.Content
FROM Comments as c
JOIN CommentsContent as cc
  ON cc.CommentId = c.CommentId
INNER JOIN
(
  select max(created) MaxDate, commentid
  from CommentsContent
  group by commentid
) cc2
  on cc.created = cc2.maxdate
  and cc.commentid = cc2.commentid
WHERE c.OwnerId = 1

请参阅SQL Fiddle with Demo