如何执行递归SQL where语句?

时间:2019-12-20 14:21:52

标签: sql sqlite

更新

感谢@forpas和@trincot在下面分享他们的解决方案和想法。我可以使用以下代码(demo):

with recursive cte_comments as (
  select 
    *
  from
    comments
  where parent_comment_id = 1
  union all
  select
    this_execution.* 
  from
    cte_comments prev_execution
    inner join comments this_execution
      on this_execution.parent_comment_id = prev_execution.comment_id
) 

select * from cte_comments

原始帖子

我在SQLite数据库中有以下comments表和数据:

表结构

-----------------------------------------
| Column            | Type              |
+++++++++++++++++++++++++++++++++++++++++
| comment_id        | integer           |
+---------------------------------------+
| parent_comment_id | integer           |
+---------------------------------------+
| comment_text      | text              |
-----------------------------------------

表格数据

--------------------------------------------------------------------
| comment_id        | parent_comment_id  | comment_text            |
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
| 1                 |                    | First comment, level 1  |
--------------------------------------------------------------------
| 2                 | 1                  | First comment, level 2  |
--------------------------------------------------------------------
| 3                 | 2                  | First comment, level 3  |
--------------------------------------------------------------------
| 4                 | 2                  | First comment, level 3  |
--------------------------------------------------------------------
| 5                 |                    | Second comment, level 1 |
--------------------------------------------------------------------
| 6                 | 5                  | Second comment, level 2 |
--------------------------------------------------------------------
| 7                 | 6                  | Second comment, level 3 |
--------------------------------------------------------------------

数据用于comment_id唯一且parent_comment_id可以为null的网站中的嵌套评论部分。两个或多个注释可以在同一parent_comment_id下。 comment_text列包含随机字符串。

问题

如何执行SQL搜索,以便在父注释下返回所有子对象?例如,当我搜索注释1下的所有注释时,我希望注释2、3和4(所有以 First comment 开头的注释)返回。当我搜索评论5下的所有评论时,我希望评论6和7(所有以第二评论开头的评论)返回。

我需要一个中介/联接表吗?我需要更改表结构吗?或者,我是否需要使用另一个数据库引擎来实现它?

2 个答案:

答案 0 :(得分:1)

使用递归CTE

with recursive cte as (
  select * from comments
  where parent_comment_id = 1
  union all
  select t.* 
  from cte c inner join comments t
  on t.parent_comment_id = c.comment_id
) 
select * from cte

请参见demo
结果:

| comment_id | parent_comment_id | comment_text           |
| ---------- | ----------------- | ---------------------- |
| 2          | 1                 | First comment, level 2 |
| 3          | 2                 | First comment, level 3 |
| 4          | 2                 | First comment, level 3 |

答案 1 :(得分:1)

如果您的sqlite版本为3.8.4或更高版本,则可以使用递归with子句:

with recursive cte (id, name, parent_id) as (
  select     comment_id,
             comment_text,
             parent_comment_id 
  from       comments
  where      parent_comment_id = 1
  union all
  select     c.comment_id,
             c.comment_text,
             c.parent_comment_id
  from       comments c
  inner join cte
          on c.parent_comment_id = cte.comment_id
)
select * from cte;

parent_comment_id = 1条件下,您会提到应该检索其后代的注释的ID。