Mysql 线程化消息的SQL查询

Mysql 线程化消息的SQL查询,mysql,sql,group-by,grouping,threaded-comments,Mysql,Sql,Group By,Grouping,Threaded Comments,我的网站有一个消息功能,一个用户可以向另一个用户发送消息。消息支持线程-父消息可以有任意数量的子消息,但只有一级深度 messages表如下所示: Messages - Id (PK, Auto-increment int) - UserId (FK, Users.Id) - FromUserId (FK, Users.Id) - ParentMessageId (FK to Messages.Id) - MessageText (varchar 200) Parent1 Chil

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

messages表如下所示:

Messages
 - Id (PK, Auto-increment int)
 - UserId (FK, Users.Id)
 - FromUserId (FK, Users.Id)
 - ParentMessageId (FK to Messages.Id)
 - MessageText (varchar 200)
Parent1
 Child1
 Child2
 Child3
Parent2
 Child1
Parent3
 Child1
 Child2
我想在一个页面上显示消息,每个“父”消息后面都是子消息的折叠视图

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

我想得到这样的信息:

Messages
 - Id (PK, Auto-increment int)
 - UserId (FK, Users.Id)
 - FromUserId (FK, Users.Id)
 - ParentMessageId (FK to Messages.Id)
 - MessageText (varchar 200)
Parent1
 Child1
 Child2
 Child3
Parent2
 Child1
Parent3
 Child1
 Child2

您可以使用临时ID对邮件进行排序。如果消息是父消息,则临时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条消息中获取消息和相应的子消息。

您可以使用临时ID来订购消息。如果消息是父消息,则临时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条消息中获得消息和相应的子消息。

试试这个。您可以使用保存在前端用于分页的某些变量替换范围

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;

试试这个。您可以使用保存在前端用于分页的某些变量替换范围

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;

什么数据库管理系统?MySQL?什么数据库管理系统?MySQL?Oracle?我希望能够一次抓取10条“家长”消息,然后抓取他们的所有孩子,这样我就可以在UI中翻阅家长消息。我希望能够一次抓取10条“家长”消息,然后抓取他们的所有孩子,这样我就可以在UI中翻阅家长消息。这应该是公认的答案。在性能方面要好得多。这应该是公认的答案。在性能方面要好得多。