如何解决递归查询以获取所有子项
我有一个 edibles
表,其定义如下:
Column | Type | Collation | Nullable | Default
--------+-----------------------+-----------+----------+---------
id | integer | | not null |
name | character varying(60) | | not null |
parent | integer | | not null |
它有如下数据:
id | name | parent
----+----------------------+--------
1 | fruit | 0
2 | veg | 0
3 | cruciferous | 2
4 | horseradish | 3
5 | colanaceae | 1
6 | tomatoes | 5
7 | aubergine | 5
8 | chinese eggplant | 7
9 | costoluto fiorentino | 6
10 | calvaceae | 0
该表是自引用的,以迎合食物的亲子关系。
我正在尝试编写一个查询来获取所有子项,无论给定的 id
嵌套如何。
期望输出
where id = 1
应该返回
id | name | parent
----+----------------------+--------
1 | fruit | 0
5 | colanaceae | 1
6 | tomatoes | 5
7 | aubergine | 5
8 | chinese eggplant | 7
9 | costoluto fiorentino | 6
where id = 10
应该返回
id | name | parent
----+----------------------+--------
10 | calvaceae | 0
最后 where id = 6
应该返回:
id | name | parent
----+----------------------+--------
6 | tomatoes | 5
9 | costoluto fiorentino | 6
我之前没有做过任何递归 SQL,我不确定从哪里开始。
我创建了一个 db-fiddle too。
更新
抱歉,忘记说了,Postgres 版本是 10。
解决方法
递归 CTE 实际上非常简单:
with recursive cte as (
select 6 as id
-------------^ just change this value
union all
select e.id
from cte join
edibles e
on e.parent = cte.id
)
select *
from cte;
Here 是一个 dbfiddle。
,架构 (PostgreSQL v12)
-- create the table
create table edibles (
id integer not null,name varchar(60) not null,parent integer not null);
-- insert data
insert into edibles (id,name,parent) values
(1,'fruit',0),(2,'veg',(3,'cruciferous',2),(4,'horseradish',3),(5,'colanaceae',1),(6,'tomatoes',5),(7,'aubergine',(8,'chinese eggplant',7),(9,'costoluto fiorentino',6),(10,'calvaceae',0);
查询 #1
with RECURSIVE cte as
(
select * from edibles where id=1
union all
select e.* from edibles e inner join cte on e.parent=cte.id
)
select * from cte;
id | 姓名 | 父 |
---|---|---|
1 | 水果 | 0 |
5 | 科兰科 | 1 |
6 | 西红柿 | 5 |
7 | 茄子 | 5 |
8 | 中国茄子 | 7 |
9 | costoluto fiorentino | 6 |
对于 ID=6
架构 (PostgreSQL v12)
查询 #2
with RECURSIVE cte as
(
select * from edibles where id=6
union all
select e.* from edibles e inner join cte on e.parent=cte.id
)
select * from cte;
id | 姓名 | 父 |
---|---|---|
6 | 西红柿 | 5 |
9 | costoluto fiorentino | 6 |
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。