得到评论及其回复

时间:2011-10-12 03:27:15

标签: sql

我有一个名为comments,的表格,其中包含以下列:idtitlecommentreply_to,create_date。它是一个PostgreSQL DB,版本8.3。 列reply_to引用正在回复的注释 我希望得到所有回复的评论。

Id / title / comment / reply_to / create_date  / reply_id / reply_title / reply_comment / reply_reply_to  / reply_create_date

7 / hello  / this is john / 6 / 2011-1-2   / 8  / Re:hello / Hello John! / 7 / 2011-1-4

7 / hello  / this is john / 6 / 2011-1-2   / 9  / Re:hello / John, welcome! / 7 / 2011-1-2

7 / hello  / this is john / 6 / 2011-1-2   / 10  / Re:hello / Nice to meet you, John / 7 / 2011-1-1

id为8的评论已被id为8,9和10的评论回复。 为此,我使用了这个查询:

Select comments.id,comments.title
      ,comments.comment
      ,comments.reply_to
      ,comments.create_date
      ,B.id as reply_id
      ,B.title as reply_title
      ,B.comment as reply_comment
      ,B.reply to as reply_reply_to
      ,B. create_date as reply_create_date
  from comments 
  left join (select * from comments) B ON comments.id=B.reply_to
 order by create_date, reply_create_date DESC

这很好,但现在我想只收到每条评论的最后两个回复,所以结果应该是:

7 / hello  / this is john / 6 / 2011-1-2   / 8  / Re:hello / Hello John! / 7 / 2011-1-4

7 / hello  / this is john / 6 / 2011-1-2   / 9  / Re:hello / John, welcome! / 7 / 2011-1-2

我认为在查询中使用limitoffset会有所帮助,但是如果我将它们放在查询的最后部分,它只需要所有注释中的2条。如果我把它们放在B查询中,只需要回复2个。

1 个答案:

答案 0 :(得分:1)

PostgreSQL 9.0 中,您的查询可能如下所示:

SELECT c.id
      ,c.title
      ,c.comment
      ,c.reply_to
      ,c.create_date
      ,b.reply_id
      ,b.reply_title
      ,b.reply_comment
      ,b.reply_reply_to
      ,b.reply_create_date
  FROM comments c
  LEFT JOIN (
    SELECT b.id          AS reply_id
          ,b.title       AS reply_title
          ,b.comment     AS reply_comment
          ,b.reply_to    AS reply_reply_to
          ,b.create_date AS reply_create_date
          ,row_number() OVER (PARTITION BY b.reply_to ORDER BY b.create_date DESC) AS rn
      FROM comments b
     WHERE rn < 3) b ON b.reply_to = c.id
 ORDER BY c.create_date, c.id, b.reply_create_date DESC;

重点

  • 使用window function row_number()获取最新的2个帖子
  • 检索您列出的列(原因不明)加上最多两个回复
  • 包含根本没有回复的评论(回复字段为NULL)