所以我正在尝试建立一个简单的论坛。它将是按主题(如果没有回复)或最新回复的日期降序排列的主题列表。这是数据库结构:
论坛主题
ID、姓名、电子邮件、正文、日期
论坛回复
id、电子邮件、正文、日期、topic_id
论坛本身将包含一个带有以下标题的 HTML 表格:
主题,上次修改,# 回复
生成这样一个结构的查询会是什么样子?我在想它会涉及交叉连接,但不确定......在此先感谢。
有点像这样:
select * from forum_topic
inner join forum_reply on forum_topic.id=topc_id
但是,不要使用select *
这是不好的做法:)
而且我不喜欢你避免标准化的方式!意思是我宁愿:
用户
线程
回复
然后像这样选择一个线程:
select ThreadID, Subject, Answered, AksedByUserID, Date from Threads
并选择所有这样的回复
select Answer, Date, Name, Email from Threads
inner join Replies on Threads,ThreaID=Replies.ThreadID
inner join Users on AskedByUserID=UserID
where Threads.ThreadID=xxx
现在这只是从我的脑海中写出来的,但您可能还需要添加一些分组依据。
是的,您应该能够通过如下查询获得它:
SELECT
forum_topic.id,
forum_topic.name AS Topic,
MAX(forum_reply.date) AS Last_Modified,
count(*) AS Replies
FROM forum_topic
INNER JOIN forum_reply ON (forum_topic.id=forum_reply.topic_id)
GROUP BY forum_topic.id
“分组依据”是每个主题为我们提供一行的魔力,MAX()和COUNT()函数为我们提供所需的聚合数据。
(编辑:我错过了第一篇文章的正文在主题表中,因此上述查询会错过没有回复的帖子。Filip 有正确的想法,建议您对数据进行规范化。一旦规范化,类似于上述的查询会给你你需要的数据)。
首先,在我看来,实际上没有人回答您的问题,即:
生成这样一个结构的查询会是什么样子?
具有要求的结构
主题,LastModified,# 回复。
给定您提供的表结构,生成具有该结构的结果表的 SQL 将是:
SELECT t.Id, t.Name AS Topic,
MAX(r.Date) AS LastModified,
COUNT(*) AS NumReplies
FROM Forum_Topic t
LEFT OUTER JOIN Forum_Reply r ON t.id = r.topic_id
GROUP BY t.Id, t.Name
(抱歉,这仅在 SQL Server 上进行了测试,因为我目前无法访问 MySql)
此外,您的结构已经标准化。相反的建议是对您想要做什么做出假设,例如,假设您对跟踪用户名以及电子邮件地址感兴趣。这是非常合理的,但仍然是一个假设。从规范化的角度来看,使用电子邮件地址作为唯一的用户标识符并没有错。
现在,如果您正在寻找有关如何设置数据库的一般建议,我们可以为您提供很多建议。在规范化之前,我会先不使用潜在的关键字作为对象名称(例如,不要给列名称,如“名称”和“日期”)。
关于 Matt 在没有回复时关于值为 NULL 的评论:使用 COALESCE() 函数将解决该问题。COALESCE() 返回第一个非 NULL 参数(如果所有参数都为 NULL,则返回 NULL)。因此,将 MAX(r.Date) 替换为 MAX(COALESCE(r.Date, t.Date))。
所谓“规范化”,是指去掉“forum_topic”的body栏目,真正的topic body应该是第一个回复?