1

所以我正在尝试建立一个简单的论坛。它将是按主题(如果没有回复)或最新回复的日期降序排列的主题列表。这是数据库结构:

论坛主题

ID、姓名、电子邮件、正文、日期

论坛回复

id、电子邮件、正文、日期、topic_id

论坛本身将包含一个带有以下标题的 HTML 表格:

主题,上次修改,# 回复

生成这样一个结构的查询会是什么样子?我在想它会涉及交叉连接,但不确定......在此先感谢。

4

4 回答 4

3

有点像这样:

select * from forum_topic
inner join forum_reply on forum_topic.id=topc_id

但是,不要使用select *

这是不好的做法:)

而且我不喜欢你避免标准化的方式!意思是我宁愿:

用户

  • 用户身份
  • 姓名
  • 电子邮件

线程

  • 线程ID
  • 学科
  • 已回答
  • AskedByUserID
  • 日期

回复

  • 回复ID
  • 线程ID
  • 用户身份
  • 回答
  • 日期

然后像这样选择一个线程:

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

现在这只是从我的脑海中写出来的,但您可能还需要添加一些分组依据。

于 2009-01-03T16:50:25.910 回答
1

是的,您应该能够通过如下查询获得它:

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 有正确的想法,建议您对数据进行规范化。一旦规范化,类似于上述的查询会给你你需要的数据)。

于 2009-01-03T16:50:57.483 回答
1

首先,在我看来,实际上没有人回答您的问题,即:

生成这样一个结构的查询会是什么样子?

具有要求的结构

主题,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))。

于 2009-01-03T20:39:58.410 回答
0

所谓“规范化”,是指去掉“forum_topic”的body栏目,真正的topic body应该是第一个回复?

于 2009-01-03T17:19:22.373 回答