选择最后一条记录并比较日期时间

时间:2014-05-04 20:08:44

标签: mysql

我正在建立一个讨论区,我希望得到一个未读主题列表。

如果主题中最后一篇文章的created_at日期时间大于当前登录用户上次查看此主题的时间,则主题应该是未读和选中的。

http://sqlfiddle.com/#!2/4e2e99/1 如果删除所有用户视图插入,则应列出所有主题。

我有三张桌子:

主题

  • ID
  • USER_ID
  • created_at

topic_posts

  • ID
  • topic_id
  • created_at

topic_user_views

  • ID
  • topic_id
  • created_at

到目前为止我的查询(但不起作用):

    SELECT DISTINCT `topics`.`id`, `topics`.`name`
        FROM `topics`
        INNER JOIN `topic_user_views`
            ON `topic_user_views`.`topic_id` = `topics`.`id`
            INNER JOIN `topic_posts` 
                ON `topic_posts`.`topic_id` = `topics`.`id`
        WHERE `topic_posts`.`created_at` > `topic_user_views`.`created_at`
            AND `topic_user_views`.`user_id` = 1 
        ORDER BY `id` DESC

我不知道如何比较某个主题的上一篇文章的created_at列帖子与该用户上次查看该主题的时间。

3 个答案:

答案 0 :(得分:1)

这是一种方法。我们将使用exists来测试在创建上一个主题帖子之前是否查看了主题。看到sql fiddle - http://sqlfiddle.com/#!2/4e2e99/11

select t.id as topic_id, t.name as topic_name
from topics t
where not exists(
  select tuv.topic_id, max(tuv.created_at) as last_view, max(tp.created_at) as last_post
  from topic_user_views tuv
  inner join topic_posts as tp
  on tuv.topic_id=tp.topic_id and tuv.created_at > tp.created_at

  group by topic_id
  having t.id=topic_id)
ORDER BY id DESC

答案 1 :(得分:1)

以下是我提出的建议:

SELECT t1.topic_id, t3.account_user_id, t1.created_at last_post_date, t4.created_at as last_seen_date
FROM topic_posts t1
INNER JOIN (SELECT topic_id, MAX(created_at) as created_at
            FROM topic_posts
            GROUP BY topic_id) t2
USING (topic_id, created_at)
INNER JOIN topic_user_views t3
USING (topic_id)
INNER JOIN (SELECT topic_id, account_user_id, created_at
                 FROM topic_user_views
                 INNER JOIN (SELECT topic_id, account_user_id, MAX(created_at) as created_at
                             FROM topic_user_views
                             GROUP BY topic_id, account_user_id) _
                 USING (topic_id, created_at, account_user_id)) t4
ON t1.topic_id = t4.topic_id and t3.account_user_id = t4.account_user_id and t3.created_at = t4.created_at
WHERE t1.created_at > t4.created_at
AND t3.account_user_id = 1;

这个想法是加入主题(t2)中最后发布的消息的日期和用户在主题中最后看到的消息的日期(t4),然后你只需要过滤掉你的结果不想要。

如果我没有弄错,在您提供的SQLFiddle中,没有用户尚未看到过的主题,因此不会返回任何内容。我稍微修改了它(you can see it here),它似乎按照需要工作。

要考虑用户从未查看过的主题,我认为最佳解决方案是将account表与RIGHT OUTER JOIN一起使用。类似于:

SELECT t1.topic_id, t3.account_user_id, t1.created_at last_post_date, t4.created_at as last_seen_date
FROM topic_posts t1
INNER JOIN (SELECT topic_id, MAX(created_at) as created_at
            FROM topic_posts
            GROUP BY topic_id) t2
USING (topic_id, created_at)
INNER JOIN topic_user_views t3
USING (topic_id)
INNER JOIN (SELECT topic_id, account_user_id, created_at
                 FROM topic_user_views
                 INNER JOIN (SELECT topic_id, account_user_id, MAX(created_at) as created_at
                             FROM topic_user_views
                             GROUP BY topic_id, account_user_id) _
                 USING (topic_id, created_at, account_user_id)) t4
ON t1.topic_id = t4.topic_id and t3.account_user_id = t4.account_user_id and t3.created_at = t4.created_at
RIGHT OUTER JOIN account
ON account.user_id = t3.account_user_id
WHERE t1.created_at > t4.created_at or t4.account_user_id IS NULL
AND t3.account_user_id = 1;

我没有测试过。

答案 2 :(得分:1)

通过此示例,如果用户还没有看到任何内容,也会选择主题:

SELECT DISTINCT
  `topics`.`id`,
  `topics`.`name`
FROM `topics`
  LEFT JOIN `topic_user_views` AS tuv
    ON `tuv`.`topic_id` = `topics`.`id`
WHERE (SELECT
         1
       FROM topic_posts AS tp
       WHERE tp.topic_id = `topics`.`id`
           AND (tp.created_at > tuv.created_at
                 OR tuv.created_at IS NULL)
       LIMIT 1)IS NOT NULL
ORDER BY `id` DESC;