Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/43.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 选择具有三个级别的注释_Php_Mysql_Sql - Fatal编程技术网

Php 选择具有三个级别的注释

Php 选择具有三个级别的注释,php,mysql,sql,Php,Mysql,Sql,我有一个存储评论的表。注释有不同的深层次,它们在一个id为和parent_id的表中相互关联。深层的最大值是三,我想用一个查询而不是三个查询来选择它们,并使用foreach三次 注释表: id title parent_id 1 'where are you?' NULL 2 "im at home" 1 3 "what is time in your count

我有一个存储评论的表。注释有不同的深层次,它们在一个id为和parent_id的表中相互关联。深层的最大值是三,我想用一个查询而不是三个查询来选择它们,并使用foreach三次

注释表:

id title                           parent_id 
 1 'where are you?'                NULL
 2 "im at home"                       1
 3 "what is time in your country?" NULL 
 4 "it's 3 pm"                        3
 5 "oh that's cool"                   4
第一级是父级id=NULL的注释 我使用以下查询获取它们:

$first = $this->db->query("SELECT title FROM comment WHERE parent_id IS NULL");
    $second = $this->db->query("SELECT title FROM comment WHERE parent_id IN (SELECT id FROM comment WHERE parent_id IS NULL)");
        $third= $this->db->query("SELECT title FROM comment WHERE parent_id IN (SELECT id FROM comment WHERE parent_id IN(SELECT id FROM comment WHERE parent_id IS NULL))");

有什么方法可以通过一个查询获取它们吗?

您可以创建递归函数/方法,它将为您执行此循环。或者使用
do,而
构造:

$parentIds = null;
do {
    $where = (is_null($parentIds)) ? 'IS NULL' : sprintf('IN (%s)', implode(',', $parentIds));

    $query = $this->db->query("SELECT title FROM comment WHERE parent_id " . $where);

    // Do something with $query data
    // In your process $query loop you must fill $parentIds with `parent_id` column value

    // ...
    $parentIds[] = $row['parent_id'];
    // ...
} while (!empty($parentIds));

由于级别的最大深度为3,因此我们可以使用两个自联接来确定父id,并使用自定义排序

如果您的MySQL/MariaDB版本不支持递归CTE,请尝试以下解决方案:

架构(MySQL v5.7)


查询#1

SELECT c1.id, c1.title, c1.parent_id 
FROM comment AS c1 
LEFT JOIN comment AS c2 ON c2.id = c1.parent_id 
LEFT JOIN comment AS c3 ON c3.id = c2.parent_id 
ORDER BY 
  CASE WHEN c1.parent_id IS NULL THEN c1.id  /* first level comment*/
       WHEN c2.parent_id IS NULL THEN c2.id  /* second level comment */
       ELSE c3.id /* comment is at third level */
  END ASC, 
  c1.id ASC;

| id  | title                         | parent_id |
| --- | ----------------------------- | --------- |
| 1   | where are you?                |           |
| 3   | im at home                    | 1         |
| 2   | what is time in your country? |           |
| 4   | its 3 pm                      | 2         |
| 5   | oh thats cool                 | 4         |


您使用的是哪个版本的MySQL?如果您使用的是MySQL 8,请查看递归CTEs:@ragol,我对此不熟悉。你能帮我写吗?我用的是15版。1@Strawberry哦,那个版本的MariaDB:))。我使用7.3.6
CREATE TABLE comment
    (`id` int, `title` varchar(33), `parent_id` varchar(4))
;

INSERT INTO comment
    (`id`, `title`, `parent_id`)
VALUES
    (1, 'where are you?', NULL),
    (2, 'what is time in your country?', NULL),
    (3, 'im at home', '1'),
    (4, 'its 3 pm', '2'),
    (5, 'oh thats cool', '4')
;
SELECT c1.id, c1.title, c1.parent_id 
FROM comment AS c1 
LEFT JOIN comment AS c2 ON c2.id = c1.parent_id 
LEFT JOIN comment AS c3 ON c3.id = c2.parent_id 
ORDER BY 
  CASE WHEN c1.parent_id IS NULL THEN c1.id  /* first level comment*/
       WHEN c2.parent_id IS NULL THEN c2.id  /* second level comment */
       ELSE c3.id /* comment is at third level */
  END ASC, 
  c1.id ASC;

| id  | title                         | parent_id |
| --- | ----------------------------- | --------- |
| 1   | where are you?                |           |
| 3   | im at home                    | 1         |
| 2   | what is time in your country? |           |
| 4   | its 3 pm                      | 2         |
| 5   | oh thats cool                 | 4         |