简体   繁体   English

MySQL将父注释下的子注释分组未返回正确的数据结果

[英]MySQL to group child comments under parent comments is not returning correct data result

My JavaScript/PHP/MySQL Project Management app I am building has a panel/div that loads in all Event/Comment records that belong to a Project Task record. 我正在构建的JavaScript / PHP / MySQL项目管理应用程序具有一个面板/ div,可加载属于项目任务记录的所有事件/评论记录

These Activity event log records tell the history of modifications done to a Task record. 这些活动事件日志记录告诉您对任务记录所做的修改的历史记录。 They alo in the same flow of things have Task Comments. 他们还在事物流中同样具有任务注释。

I am now trying to add Comment threading/child/sub-comments. 我现在正在尝试添加评论线程/子/子评论。

My screenshot below show an example on the 5 record down from the top right is an indented comment that appears to be a sub-comment/child of the comment record above it (number 4). 我下面的屏幕截图显示了右上角第5条记录中的一个示例,该示例是缩进的注释,该注释似乎是其上方注释记录(第4个)的子注释/子注释。

click to view full size image 点击查看原图 在此处输入图片说明

Now if you view the DOM HTML structure you will see a child comment is no different than the parent comment in the flow of the HTML. 现在,如果您查看DOM HTML结构,您将看到子注释与HTML流程中的父注释没有区别。 Meaning the child comment is not a child node in the HTML. 意味着子注释不是HTML中的子节点。 Instead a child comment is below the parent comment and simply has a CSS class to say it is a child comment which applies a margin-left CSS value and a smaller width . 相反,子注释位于父注释的下方,仅具有一个CSS类来表示这是一个子注释,该注释应用了margin-left CSS值和较小的width

在此处输入图片说明


MySQL Database Table MySQL数据库表

--
-- Table structure for table `updates_stream`
--

CREATE TABLE IF NOT EXISTS `updates_stream` (
`id` int(18) NOT NULL,
  `event_type` varchar(10) DEFAULT 'comment',
  `comment_id` int(36) DEFAULT NULL,
  `comment_parent_id` int(36) DEFAULT '0',
  `record_id` char(36) DEFAULT NULL,
  `modified_user_id` int(36) DEFAULT NULL,
  `record_name` varchar(255) DEFAULT NULL,
  `date_entered` datetime DEFAULT NULL,
  `date_modified` datetime DEFAULT NULL
) ENGINE=InnoDB AUTO_INCREMENT=1092 DEFAULT CHARSET=utf8;

SQL Query that I attempted to use to get Child comments under parnet comments (undesired results) 我试图用来在parnet注释下获取子注释的SQL查询(不需要的结果)

SELECT * FROM updates_stream AS parent
LEFT JOIN updates_stream AS child 
ON child.comment_parent_id = parent.id
WHERE parent.comment_parent_id = '0'
ORDER BY parent.id, child.id;

On to my question now... 现在我的问题...

How can I query MySQL to get all records like normal but now I need to put all child comments under the parent comments. 我如何查询MySQL以获取所有正常记录,但是现在我需要将所有子注释放在父注释下。

My MYSQL code above is set up on a SQLFiddle demo to test with here: http://sqlfiddle.com/#!9/08396/4 我上面的MYSQL代码是在SQLFiddle演示中设置的,可以在此处进行测试: http : //sqlfiddle.com/#!9/08396/4

What I need: 我需要的:

Based on my requirements, the output of my demo which has 6 records should be in this ID order: 根据我的要求,具有6条记录的演示的输出应按此ID顺序排列:

-- ID=1
-- ID=2
------- ID=3: child comment ID 3 has a Parent ID comment of 2
------- ID=5: child comment ID 5 has a Parent ID comment of 2
-- ID=4
-- ID=6

What I Got (Broken!): 我得到了(破碎!):

Instead the result on the demo is like below... Only 5 rows instead of all 6. COmment with ID:2 is listed 2 times in a row which is somewhat correct almost meaning that the 1 comment that has child comments is ID2 which has 2 child comments. 相反,演示中的结果如下所示:仅5行而不是全部6行。ID:2的COmment连续列出2次,这几乎是正确的,几乎意味着具有子注释的1条注释是ID2,具有2条儿童评论。 Also if you scroll way over to the right side of the page on the rows for ID2 you will actually see ID 3 and 5 to the right side but in the same column!: 另外,如果您滚动到ID2行的页面右侧,您实际上会在同一列的右侧看到ID 3和5!

-- ID=1
-- ID=2  ==>  ID3
-- ID=2  ==>  ID5
-- ID=4
-- ID=6

I don't know if what you are wanting can be done is SQL. 我不知道您想要做的是SQL。 I have done something similar with nested menus in php though and it should work here. 我已经用php中的嵌套菜单做了类似的事情,它应该在这里工作。

First, a slight change to your query: 首先,对查询稍作更改:

SELECT 
    * 
FROM 
    updates_stream
ORDER BY comment_parent_id;

For this to work, we will also need to define a class for your comments: 为此,我们还需要为您的注释定义一个类:

class Comment{
    public $id;
    public $comment = '';
    ....
    //Do not need any reference to the parent.
    //Used to tell how nested the comment is (Child of child, etc.)
    public $nest_lvl = 0;
    public $children = array();

    public function generateHtml(){...}
}

So what we want to do is loop through our result set, create an instance of the class for every comment. 因此,我们想要做的是遍历结果集,为每个注释创建一个类的实例。 We will have two arrays, one for setting up the format, and another for easy access to parent comments: 我们将有两个数组,一个用于设置格式,另一个用于轻松访问父注释:

$parentComments = array();
$nestedComments = array();

while($row = mysqli_fetch_assoc($result)){
    $comment = new Comment();
    //Set comment values;

    if($row['parent_id'] != 0){
        //Add this comment to the parent comment children array
        $comment->nest_lvl = $parentComments[$row['parent_id']]->nest_lvl + 1;
        $parentComments[$row['parent_id']]->children[] = $comment;
    } else {
        //Add this comment to the nested array. Only comments that are not a child
        //comment should be added to the nested array, otherwise they will display twice.
        $nestedComments [] = $comment;
    }

    //Add this comment to the parent array
    $parentComments[$comment->id] = $comment;
 }

 unset($parentComments);
 mysqli_free_result($result);

Since we are using classes, everything is done by reference. 由于我们使用的是类,因此所有操作都是通过引用完成的。 Therefore, when we alter an instance of a class in $parentComments , the change will also reflect in the same instance of the class in $nestedComments . 因此,当我们更改$parentComments中的类的实例时,更改还将反映在$nestedComments中的类的同一实例中。

Back to the function in the Comment class. 回到Comment类中的函数。 This function will generate the the HTML needed for the parent comment AND all of its children (recursively). 此函数将生成父注释及其所有子注释(递归)所需的HTML。 So the implimentation of this function would look something like this: 因此,此功能的实现如下所示:

public function generateHtml(){
    //Generete the html for the current comment.
    //If the children array is not empty, call generateHtml on each of them.
    foreach($this->children as $child){
        $child->generateHtml();
    }
}

You can optionally choose to pass the nest lvl into the function instead of having it in the class. 您可以选择将嵌套lvl传递给函数,而不是将其包含在类中。

Finally, to display everything, just loop through the $nestedComments , calling generateHtml() on each of them: 最后,要显示所有内容,只需遍历$nestedComments ,对它们中的每一个调用generateHtml()

foreach($nestedComments as $comment){
    $comment->generateHtml();
}

While it is not all in SQL, it will get the job done and is a lot easier to do then in SQL. 虽然在SQL中还不是全部,但是它将完成工作,并且比在SQL中容易得多。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM