嵌套注释系统mysql排序
好的,我意识到有很多方法来完成评论。我选择的方式是这样设置一张桌子嵌套注释系统mysql排序,mysql,database,comments,sql-order-by,Mysql,Database,Comments,Sql Order By,好的,我意识到有很多方法来完成评论。我选择的方式是这样设置一张桌子 id comment date time orig_comment 1 Hello 03-01-2013 10:10:10 0 2 Hello 03-02-2013 10:10:10 0 3 Hello 03-03-2013 10:10:10 1 因此,clearify有一个第一级,然后用户可以回复该评论(这是仅有的两个
id comment date time orig_comment
1 Hello 03-01-2013 10:10:10 0
2 Hello 03-02-2013 10:10:10 0
3 Hello 03-03-2013 10:10:10 1
因此,clearify有一个第一级,然后用户可以回复该评论(这是仅有的两个级别)。我给每个唯一的递增id,并指定orig_注释。如果原始注释为“0”,则它是一个基本级别的注释,如果它是嵌套的,则原始注释将是原始注释的id。很简单。因此,我需要的意见是有序的,当然。以下是我目前的做法
mysql_query("SELECT Comments.* FROM Comments ORDER BY
IF(Comments.orig_comment = 0, Comments.id, Comments.orig_comment)DESC,Comments.id ASC")
这可以首先获取最新的注释(这是我想要的),但是当涉及到嵌套注释时,它会按最早的注释排序(不是我需要的)。我需要从最新到最旧的顺序排列主要评论,任何回复也应该从最新到最旧排序。我试图修改我的查询来实现这一点,但没有成功,但无法解决它
作为一个附带问题,从实用性的角度来看,这个系统有意义吗?你认为以这种方式排序嵌套注释会让人困惑吗?我之所以想这样做,是因为我的回复按钮位于基本注释上,单击后会在基本注释的正下方添加一个文本区域。我只是觉得如果你的帖子也出现在基本评论的正下方,而不是一路被扔到嵌套回复的底部,那么你会更容易看到你的帖子。有什么想法吗
还想解决另一个问题,我用这个页面的评论。我可以使用一个简单的限制来获得x个评论,如下所示:
mysql_query("SELECT Comments.* FROM Comments ORDER BY
IF(Comments.orig_comment = 0, Comments.id, Comments.orig_comment)DESC,Comments.id ASC
LIMIT 0, $page")
这种方法显然不关注每个主要评论的回复数量。因此,我最终切断了对最后一条主要评论的回复。我只想在orig_comment='0'时强制执行该限制,这样无论有多少回复都会显示所有回复。我试过了
mysql_query("SELECT Comments.* FROM Comments ORDER BY
IF(Comments.orig_comment = 0, Comments.id, Comments.orig_comment)DESC,Comments.id ASC
LIMIT 0, SELECT COUNT(id)FROM Comments WHERE orig_comment='0' LIMIT $page")
不过,这会引发语法错误。多亏了您评论中的答案,我尝试并找到了一个解决方案,它不是很漂亮,但似乎完成了任务
SELECT *, CASE orig_comment
WHEN 0 THEN CONCAT_WS('.',id,LPAD((SELECT MAX(id)+1 FROM Comments WHERE orig_comment = C.id),3,'0'))
ELSE CONCAT_WS('.',orig_comment,LPAD(id,3,'0'))
END AS sort
FROM Comments as C
ORDER BY sort DESC
输出将是:
id comment time orig_comment sort
2 Hello "2013-03-21 16:19:00" 0 2.005
3 Hello "2013-03-21 16:19:00" 2 2.003
4 Hello "2013-03-21 16:19:00" 2 2.004
1 Hello "2013-03-21 16:19:00" 0 1
这在排序时不会造成麻烦,最多允许999个子注释(由于LPAD值为3)
它所做的是创建一个排序字符串,然后将其转换为十进制以获得正确的排序。(不过我认为mysql无论如何都能正确处理。)
尽管这是可行的,但我建议先计算排序值,然后为基本级别的注释创建一个良好的值。(可以将其设置为2.9或任何适合您需要的设置)考虑一下这个例子
DROP TABLE IF EXISTS comments;
CREATE TABLE comments
(comment_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,comment VARCHAR(50) NOT NULL
,comment_date DATETIME
,parent_id INT NULL
);
INSERT INTO comments VALUES
(1 ,'Hello', '2013-03-01 10:10:10',NULL),
(2 ,'Bonjour', '2013-03-02 10:10:10',NULL),
(3 ,'How are you?', '2013-03-03 10:10:10',1),
(4 ,'I\'m fine thank you, and you?', '2013-03-04 10:10:10',1),
(5 ,'Ça va?', '2013-03-05 10:10:10',2),
(6 ,'Je vais bien, merci, et toi?', '2013-03-06 10:10:10',2),
(7 ,'Yes, not too bad thanks', '2013-03-07 10:10:10',1),
(8 ,'Oui, comme ci comme ça.', '2013-03-08 10:10:10',2),
(9 ,'Bon, à bientôt.', '2013-03-09 10:10:10',2),
(10 ,'See you soon', '2013-03-10 10:10:10',1);
SELECT *
FROM comments
x
JOIN comments y
ON y.parent_id = x.comment_id
ORDER
BY x.comment_date
, y.comment_date;
+------------+---------+---------------------+-----------+------------+------------------------------+---------------------+-----------+
| comment_id | comment | comment_date | parent_id | comment_id | comment | comment_date | parent_id |
+------------+---------+---------------------+-----------+------------+------------------------------+---------------------+-----------+
| 1 | Hello | 2013-03-01 10:10:10 | NULL | 3 | How are you? | 2013-03-03 10:10:10 | 1 |
| 1 | Hello | 2013-03-01 10:10:10 | NULL | 4 | I'm fine thank you, and you? | 2013-03-04 10:10:10 | 1 |
| 1 | Hello | 2013-03-01 10:10:10 | NULL | 7 | Yes, not too bad thanks | 2013-03-07 10:10:10 | 1 |
| 1 | Hello | 2013-03-01 10:10:10 | NULL | 10 | See you soon | 2013-03-10 10:10:10 | 1 |
| 2 | Bonjour | 2013-03-02 10:10:10 | NULL | 5 | Ça va? | 2013-03-05 10:10:10 | 2 |
| 2 | Bonjour | 2013-03-02 10:10:10 | NULL | 6 | Je vais bien, merci, et toi? | 2013-03-06 10:10:10 | 2 |
| 2 | Bonjour | 2013-03-02 10:10:10 | NULL | 8 | Oui, comme ci comme ça. | 2013-03-08 10:10:10 | 2 |
| 2 | Bonjour | 2013-03-02 10:10:10 | NULL | 9 | Bon, à bientôt. | 2013-03-09 10:10:10 | 2 |
+------------+---------+---------------------+-----------+------------+------------------------------+---------------------+-----------+
如果要先使用最新的进行排序,不应该是Comments.id DESC吗?IF没有说按id对基本级别进行降序,而按origin\u注释对其他级别进行降序。您可以改为使用case语句:这样做的结果是将最新的回复放在顶部,前面没有任何基本注释。我也试着整合那篇文章中的问题,但最后我还是在顶部给出了一个回复,之前没有任何基本评论;在任何一天都可能有数百条评论发布。我宁愿按id排序(这看起来是一个简单的查询修改),所以无论它是什么时候发布的,它仍然可以正确排序。我该如何对这些结果进行分页(我原始帖子的最后一段)?根据我的示例,日期和时间应该是一个单独的列,但如果id对您有效,那么也可以。关于分页问题有什么想法吗?关于分页,我个人的观点是,您应该在单个查询中返回整个结果,然后在应用程序层中进行分页,而每次都不点击数据库。很多人不同意这种方法,但我的论点是这样的:假设您按逆时间顺序返回结果,每页一个结果。阅读一个页面需要5秒钟,在这段时间内,其他人发布了一个响应。然后,当你向前翻页时,你又看到了上一页!但我不是这方面的专家,我对使用LPAD完全不熟悉。因此,为了尝试查看查询的功能,它基本上会将.reply\u id添加到基本注释(如果是回复),并将.orig\u id添加到基本注释(如果是基本注释)。然后它使用十进制值将它们从base_comment.base_comment排序到base_comment.last_reply?也许我遗漏了什么,对吗?如果是这样的话,我应该如何事先计算十进制值呢?在我的表格中添加一列,并计算每次回复的次数?当一个被删除时,我是否需要重新计算?@dminicrick1 LPAD只是用n个字符填充一个字符串。你可以了解它的功能。如果你删除评论,我看不出排序会受到影响。(我添加了输出,以便您可以跟踪发生的情况)。注释(id 2)的排序为2.005,因为它有两个子注释,其中最高的id为4。要使基本注释在其他注释之前排序,您必须创建一个“更高的数字”,这可以通过我解释的不同方式完成。计算:回复时,只需创建排序十进制值。尽管此解决方案仅支持1级子注释。