递归查询以获取所有 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

View on DB Fiddle

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

View on DB Fiddle