SET search_path='tmp';
DROP TABLE targets CASCADE;
CREATE TABLE targets
( id integer not null primary key
, parent_id integer references targets(id)
, expected_target integer
);
INSERT INTO targets(id,parent_id,expected_target) VALUES
(1,NULL, 1000), (2,1, 500), (3,2, 200);
WITH RECURSIVE zzz AS (
SELECT t0.id, t0.parent_id
, 0::integer AS level
, t0.expected_target
FROM targets t0
WHERE t0.parent_id IS NULL
UNION
SELECT t1.id, t1.parent_id
, 1+zzz.level AS level
, t1.expected_target
FROM targets t1
JOIN zzz ON zzz.id = t1.parent_id
)
SELECT * FROM zzz
;
ВЫВОД:
SET
DROP TABLE
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "targets_pkey" for table "targets"
CREATE TABLE
INSERT 0 3
id | parent_id | level | expected_target
----+-----------+-------+-----------------
1 | | 0 | 1000
2 | 1 | 1 | 500
3 | 2 | 2 | 200
(3 rows)
ОБНОВЛЕНИЕ: если вы не хотите всего дерева, истинного дерева и ничего, кроме дерева , а только его поддеревья, вы, конечно, можете немного изменить условия:
WITH RECURSIVE zzz AS (
SELECT t0.id, t0.parent_id
, 0::integer AS level
, t0.expected_target
FROM targets t0
-- WHERE t0.parent_id IS NULL
WHERE t0.id = 2
UNION
SELECT t1.id, t1.parent_id
, 1+zzz.level AS level
, t1.expected_target
FROM targets t1
JOIN zzz ON zzz.id = t1.parent_id
)
SELECT * FROM zzz
;