2013-03-21 92 views
0

好吧,我意识到有很多方法可以完成评论。我选择的方式是这样设置的一张桌子。嵌套评论系统mysql订购

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 

因此,要清除有第一级,然后用户可以回复该评论(这是唯一的两个级别)。我给每个唯一递增的id,并指定orig_comment。如果orig_comment是“0”,那么它是基本级别的评论,如果它是嵌套的,则orig_comment将是原始评论的ID。够简单。所以我当然需要评论。以下是我现在如何做到这一点。

mysql_query("SELECT Comments.* FROM Comments ORDER BY 
IF(Comments.orig_comment = 0, Comments.id, Comments.orig_comment)DESC,Comments.id ASC") 

此作品获得第一检索(这是我想要什么)的最新评论,但是当涉及到嵌套评论它的最古老的预定他们第一个(不是我所需要)。我需要订购从最新到最旧的主要评论,任何回复也应从最新到最旧排序。我试图没有成功修改我的查询来做到这一点,但无法弄清楚。

作为一个侧面的问题,从系统角度来看,这个系统是否有意义?你是否认为以这种方式排列嵌套评论会令人困惑?我想这样做是因为我的回复按钮位于基本评论上,一旦点击就在基本评论下面添加一个textarea。我只是认为,如果它看起来好像比基本评论低,而不是一直抛到嵌套答复的底部,那么看到你的帖子会更容易。对此有何想法?

也想解决另一个问题,我用它来页面评论。我可以用一个简单的限制只得到评论的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") 

虽然这会引发语法错误。

+0

它不应该是Comments.id DESC如果你想与最新的第一个排序? IF不是说按基准降序排列,而是按origin_comment降序排列。你可以使用case语句代替:http:// stackoverflow。com/questions/3550942/can-you-add-if-statement-in-php-mysql-order-by – apelsinapa 2013-03-21 02:35:07

+0

这样做最终将最新的答复放在最前面,没有任何基本评论。我也试图整合来自那篇文章的查询,但是最后我在最前面得到了一个没有基础评论的回复。 – dminicrick1 2013-03-21 02:50:04

回答

0

感谢您的评论中的答案,我试过并找到了解决方案,它不是很漂亮,但它似乎完成了工作。

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或任何将满足您的需求)

+0

我完全不熟悉使用LPAD。因此,试图查看查询的内容......它基本上将.reply_id添加到基本评论(如果它是回复),并将.orig_id添加到基本评论(如果它是基本评论)。然后它使用十进制值将它们从base_comment.base_comment订购到base_comment.last_reply?也许我错过了一些东西,对吗?如果是这样,我将如何预先计算小数值?在我的表格中添加一列并计算每次回复的时间?那么我是否需要重新计算何时被删除? – dminicrick1 2013-03-21 17:05:17

+0

@ dminicrick1 LPAD只是用n个字符填充一个字符串。你可以选择它做什么。如果删除评论,我看不到排序会受到影响。 (我添加了输出,所以你可以关注发生的事情)。评论(id 2)将有一个排序2.005,因为它有两个子注释,最高的id是4.为了让基本评论排序在其他评论之前,你必须创建一个“更高的数字”,这可以是正如我解释的那样以不同的方式完成要计算:在做出回复时,只需创建排序十进制值。虽然这个解决方案只支持1级子注释。 – apelsinapa 2013-03-21 17:38:44

0

考虑这个例子...

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 | 
+------------+---------+---------------------+-----------+------------+------------------------------+---------------------+-----------+ 
+0

我不能按日期排序,因为这太宽泛;在任何一天,可能会有数百条评论发布。我宁愿保持它由id排序(它看起来是一个简单的模式到您的查询),所以不管它什么时候发布它仍然会被正确排序。我将如何去分页这些结果(我的原始文章的最后一部分)? – dminicrick1 2013-03-21 16:56:16

+0

按照我的例子,日期和时间应该是单列,但是如果id适合你,那也没问题。 – Strawberry 2013-03-21 17:03:47

+0

好的。有关分页问题的任何想法? – dminicrick1 2013-03-21 17:09:40