SQL检查线程时间戳是否比JOIN语句中的回复时间戳更新

时间:2018-04-16 17:06:30

标签: mysql sql

所以我对SQL加入有点新意,并且可能正在考虑全面过度杀戮。 我想要做的就是将我的四张桌子连在一起。

我想要完成的是我想从类别中获取所有信息,并且我希望它与具有最新时间戳的回复匹配,然后我想加入t.title,其中t.id匹配r.thread_id

SELECT c.*, t.id, t.title, r.timestamp, u.id, u.username
FROM forum_category AS c 
LEFT JOIN forum_threads AS t ON (c.id = t.category_id)
LEFT JOIN forum_replies AS r ON (t.id = r.thread_id 
     AND r.timestamp = 
     (
         SELECT timestamp 
         FROM forum_replies 
         ORDER BY timestamp DESC LIMIT 1
    ))
LEFT JOIN users AS u ON (r.user_id = u.id)
GROUP BY c.id

现在这个代码似乎可以工作,而不是很多测试。

但是我需要扩展它以检查t.timestamp是否比最新的r.timestamp更新并且然后加入那个。使用t.title,t.timestamp和t.user_id。

因此,如果一个帖子比最新的回复更新。 我知道我可以把第一篇文章作为回复并以这种方式解决。但是,如果可以在SQL语句中解决,我现在就不这样做。

SQL布局在这里: https://imgur.com/a/nCn2a

forum_category:

thread table

forum_threads: thread table forum_replies:
reply table

1 个答案:

答案 0 :(得分:1)

一种有用的技术是使用子查询来分解查询尝试执行的操作的心理逻辑。基本上,子查询代替任何查询中的常规表。

所以,首先,我们需要在每个帖子的回复中获取最新的时间戳:

select thread_id, max(timestamp) as LatestReply
from forum_replies
group by thread_id

我们称之为MostRecentThreadSubquery。所以,它会让我们做类似的事情:

select * from
forum_threads t
LEFT JOIN
(
    select thread_id, max(timestamp) as LatestReply
    from forum_replies
    group by thread_id
) as MostRecentThreadSubquery
on t.thread_id = MostRecentThreadSubquery.thread_id

有意义吗?我们不再针对forum_replies表加入forum_threads表 - 我们已经创建了一个子查询来帮助我们列出每个线程ID的最新回复。

现在,我们添加SQL CASE语句,以获得类似:

select
    thread_id,
    CASE WHEN t.timestamp > MostRecentThreadSubquery.LatestReply
        THEN t.timestamp
        ELSE MostRecentThreadSubquery.LatestReply
    END as MostRecentTimestamp
from -- ... the rest of that earlier SQL statement

好的,现在我们有一个查询,对于每个thread_id,都有最新的时间戳 - 无论是来自forum_replies还是来自forum_threads表。

......你猜对了。我们要再做一个子查询。我们称之为MostRecentPerThread

select *
from forum_category AS c
LEFT JOIN
(
    -- ... that previous query ...
) as MostRecentPerThread
on c.thread_id = MostRecentPerThread.thread_id

有意义吗?您正在使用子查询作为逻辑上将查询分解为更小组件的方法。你不再有一个巨大的查询。你有一个小的子查询,它只是得到最近回复的时间戳。你有一个小的子查询,它将第一个子查询与线程表进行比较,以获得最新的时间戳。并且您有一个主查询,它使用第二个子查询将其与类别表合并。