递归查询以获取所有 children
recursive query to get all children
我有一个 edibles
table 具有以下定义:
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
table 是 self-referencing 以迎合食用的 parent-child 关系。
我正在尝试编写一个查询,无论给定的 id
.
如何嵌套,我都会获取所有 children
期望输出
where id = 1
应该 return
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
应该 return
id | name | parent
----+----------------------+--------
10 | calvaceae | 0
最后 where id = 6
应该 return:
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 是一个 db<>fiddle.
模式(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', 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);
查询#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
name
parent
1
fruit
0
5
colanaceae
1
6
tomatoes
5
7
aubergine
5
8
chinese eggplant
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
name
parent
6
tomatoes
5
9
costoluto fiorentino
6
我有一个 edibles
table 具有以下定义:
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
table 是 self-referencing 以迎合食用的 parent-child 关系。
我正在尝试编写一个查询,无论给定的 id
.
期望输出
where id = 1
应该 return
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
应该 return
id | name | parent
----+----------------------+--------
10 | calvaceae | 0
最后 where id = 6
应该 return:
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 是一个 db<>fiddle.
模式(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', 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);
查询#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 | name | parent |
---|---|---|
1 | fruit | 0 |
5 | colanaceae | 1 |
6 | tomatoes | 5 |
7 | aubergine | 5 |
8 | chinese eggplant | 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 | name | parent |
---|---|---|
6 | tomatoes | 5 |
9 | costoluto fiorentino | 6 |