获取QA表中的线程的最新行

时间:2012-11-01 09:58:55

标签: mysql sql

这是我的SQL表的简化版本,用于问答,post_id是主键。

 post_id | ref_post_id | title  | date (unix timestamp)
   1     |     0       | Title1 |  10 
   2     |     1       |        |  20 
   3     |     0       | Title2 |  30 

当ref_post_id为0时,这意味着它是一个问题。当它不为0时,它是答案,其中数字对应于问题的post_id。这意味着第二行是上例中第一行的答案。

我想要做的只是获得每个问题的最后一行。如果问题没有任何答案我想要问题行,但如果它有答案我想要最后一个答案,但我想加入属于问题行的标题。

我已经用Google搜索并尝试了一段时间了。希望你能理解我的问题!

谢谢!

5 个答案:

答案 0 :(得分:2)

我建议将你的桌子拆分为两个,一个用于问题,另一个用于答案。

这是一个粗略的草图:

questions
post_id  |  title  |  date

answers
answer_id  |  post_id  |  answer  |  date

通过这种方式,您可以通过以下方式请求所请求问题的最后答案:

SELECT * FROM answers WHERE post_id = THE_REQUESTED_POST_ID ORDER BY date DESC LIMIT 1

编辑:

对不起,我说错了表,选择的表应该是答案。

答案 1 :(得分:1)

SELECT  a.*, b.replyID
FROM    tableName a
        LEFT JOIN tableName c
            ON a.ref_post_ID = c.post_id
        LEFT JOIN
        (
            SELECT ref_post_ID replyID, MAX(DATE) as maxDATE
            FROM tableName
            GROUP BY replyID
        ) latestAnswer
            ON  c.ref_post_ID = latestAnswer.replyID AND
                c.date = latestAnswer.maxDATE

我强烈建议您为此创建一个单独的表,一个用于Question,第二个用于AnswersAnswers表中的一列是来自{{1}的外来词表格。

答案 2 :(得分:0)

我建议将你的表分成两个不同的表,一个用于问题,另一个用于答案。

但是,您需要的查询可以写成:

SELECT posts.*
FROM
  posts INNER JOIN
    (SELECT IF(ref_post_id=0,post_id,ref_post_id) as id, Max(Date) as maxdate
     FROM posts
     GROUP BY id) p
  ON
    (p.maxdate = posts.date) AND
    (p.id =IF(posts.ref_post_id=0,posts.post_id,posts.ref_post_id))

要选择每个问题/答案的最长日期,您必须按ref_post_id进行分组,但ref_post_id = 0必须按post_id分组的情况除外,因此IF。< / p>

当您使用子查询加入posts表时,您必须使用相同的技巧。

编辑:如果您需要将问题标记为已删除,那么您必须从上面的选择中删除所有已删除的问题和答案,并且您必须再使用一个子查询来选择未删除的问题:

SELECT posts.*
FROM
  posts INNER JOIN
    (SELECT IF(ref_post_id=0,post_id,ref_post_id) as id, Max(Date) as maxdate
     FROM posts
     WHERE EXISTS (SELECT null 
                   FROM posts posts_sub
                   WHERE
                     posts_sub.post_id =
                     IF(posts.ref_post_id=0,posts.post_id,posts.ref_post_id)
                   AND posts_sub.deleted =0)
     GROUP BY id) p
  ON
    (p.maxdate = posts.date) AND
    (p.id =IF(posts.ref_post_id=0,posts.post_id,posts.ref_post_id))

答案 3 :(得分:0)

这个怎么样:

SELECT t.*, lastAnswer.title  FROM tableName t LEFT JION 
(SELECT t1.*
    FROM tableName t1 LEFT JOIN tableName t2
     ON (t1.ref_post_id = t2.ref_post_id AND t1.date < t2.date)
    WHERE t2.ref_post_id IS NULL AND t1.ref_post_id > 0
) lastAnswer
ON t.post_id = lastAnswer.ref_post_id
WHERE t.ref_post_id = 0

答案 4 :(得分:0)

我已经发布了一个解决方案,但假设post_id始终是有序的,我更喜欢这个,因为它更简单:

select
  posts.*, posts_1.title
from
  posts left join posts posts_1
  on posts.ref_post_id = posts_1.post_id
where posts.post_id IN (select max(post_id) from posts
group by IF(posts.ref_post_id=0,posts.post_id,posts.ref_post_id))

(我使用ref_post_idpost_id分组的相同技巧。

编辑:如果您只需要选择未删除的帖子,这就是您所需要的:

select
  posts.*,
  posts_1.title
from
  posts left join posts posts_1
  on posts.ref_post_id = posts_1.post_id
where
  posts.post_id IN (select max(post_id) from posts
                    where exists (select * 
                      from posts posts_sub
                      where
                        posts_sub.post_id =
                        if(posts.ref_post_id=0,posts.post_id,posts.ref_post_id)
                        and posts_sub.deleted =0)
group by
  IF(posts.ref_post_id=0,posts.post_id,posts.ref_post_id))