sql - 基于邻接表递归查询分层数据

标签 sql postgresql hierarchical-data recursive-query

学习SQL,有点问题。我有 2 个表 levellevel_hierarchy

|name        | id |     |parent_id | child_id|
-------------------     ---------------------
| Level1_a   | 1  |     | NULL     |    1    |
| Level2_a   | 19 |     | 1        |    19   |
| Level2_b   | 3  |     | 1        |    3    |
| Level3_a   | 4  |     | 3        |    4    |
| Level3_b   | 5  |     | 3        |    5    | 
| Level4_a   | 6  |     | 5        |    6    | 
| Level4_b   | 7  |     | 5        |    7    | 

现在我需要的是一个查询,该查询将根据标记我要从哪个级别层次结构级别获取条目的参数从每个层次结构级别返回表 level 中的所有条目。

获取 Level1 条目非常容易。

SELECT name FROM level INNER JOIN level_hierarchy ON level.id = 
level_hierarchy.child_id WHERE level_hierarchy.parent_id=NULL

Level2 条目:

Level2_a
Level2_b

只是那些有父级的,而他们的父级的父级是 NULL 等等。这就是我怀疑递归的用武之地。

有没有人可以指导一下?

最佳答案

你对第一层的查询(这里是depth以区别于表格)应该是这样的:

select l.name, h.child_id, 1 as depth 
from level l
join level_hierarchy h on l.id = h.child_id 
where h.parent_id is null;

   name   | child_id | depth 
----------+----------+-------
 Level1_a |        1 |     1
(1 row)

注意 is null 的正确使用(不要使用 =null 进行比较,因为它总是给出 null).

您可以将以上内容用作递归 cte 中的初始查询:

with recursive recursive_query as (
    select l.name, h.child_id, 1 as depth 
    from level l
    join level_hierarchy h on l.id = h.child_id 
    where h.parent_id is null
union all
    select l.name, h.child_id, depth + 1
    from level l
    join level_hierarchy h on l.id = h.child_id
    join recursive_query r on h.parent_id = r.child_id
)
select *
from recursive_query
-- where depth = 2

   name   | child_id | depth 
----------+----------+-------
 Level1_a |        1 |     1
 Level2_b |        3 |     2
 Level2_a |       19 |     2
 Level3_a |        4 |     3
 Level3_b |        5 |     3
 Level4_a |        6 |     4
 Level4_b |        7 |     4
(7 rows)    

关于sql - 基于邻接表递归查询分层数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51350908/

相关文章:

mysql - 分组结果集 - mysql

sql - 数据库计算列未在 EF 4.1 中生成

sql - 为什么这两个带有否定 WHERE 子句的 SELECT COUNT(*) 总结不正确?

sql - PostgreSQL:查找到目前为止的连续天数

sql - SQL Server 中的完全递归员工-老板关系

sql - Oracle:分层查询中的编号组

php - 使用 php 进行 Mysql 日期时间输入

postgresql - 安装libpq-dev包报错

php mysql替代在循环内再次使用相同的查询

php - 在 Doctrine 语句中添加一个 Having 子句