【问题标题】:SQL Querying for Threaded Messages线程化消息的 SQL 查询
【发布时间】:2012-03-30 16:46:26
【问题描述】:

我的网站有一个消息功能,一个用户可以向另一个用户发送消息。消息支持线程 - 父消息可以有任意数量的子消息,但只有一层深。

消息表如下所示:

Messages
 - Id (PK, Auto-increment int)
 - UserId (FK, Users.Id)
 - FromUserId (FK, Users.Id)
 - ParentMessageId (FK to Messages.Id)
 - MessageText (varchar 200)

我想在页面上显示消息,每个“父”消息后跟子消息的折叠视图。

我可以使用 GROUP BY 子句或类似结构在一个查询中检索父消息和子消息吗?现在我只检索父消息,然后遍历它们并对每个消息执行另一个查询以获取所有相关的子消息。

我想收到这样的消息:

Parent1
 Child1
 Child2
 Child3
Parent2
 Child1
Parent3
 Child1
 Child2

【问题讨论】:

  • 什么DBMS系统? MySQL?甲骨文?

标签: mysql sql group-by grouping threaded-comments


【解决方案1】:

试试这个。您可以使用保留在前端的一些变量来替换 range_ 以进行分页。

select child.MessageText from
(select @i:=@i+1 as range_, id, MessageText from messages, (select @i:=0) k where ParentMessageId is null order by id asc) parent 
left outer join messages child on (parent.id = child.ParentMessageId or parent.id = child.id)
where parent.range_ between 1 and 3;

【讨论】:

  • 这应该是公认的答案。在性能方面要好得多。
【解决方案2】:

您可以使用临时 ID 对消息进行排序。如果消息是 Parent,则临时 ID 将等于 ID,否则临时 ID 将等于 ParentMessageID。然后你只需要通过临时ID订购

SELECT Messages.*, 
CASE WHEN ParentMessageId IS NULL THEN Id ELSE ParentMessageId END AS tempId 
FROM Messages
ORDER BY tempId

编辑

如果您想要前 10 条记录,您可以先获取 Id,然后运行查询

SELECT Messages.*, 
CASE WHEN ParentMessageId IS NULL THEN Id ELSE ParentMessageId END AS tempId 
FROM Messages
WHERE Messages.tempId IN (SELECT Messages.Id 
                      FROM Messages
                      WHERE ParentMessageId IS NULL
                      LIMIT 10
                      ORDER BY Messages.Id )
ORDER BY tempId

这样您只能从前 10 条消息中获取消息和相应的子项。

【讨论】:

  • 我希望能够一次抓取 10 条“父”消息,然后抓取他们所有的孩子,这样我就可以在 UI 中翻阅父消息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多