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
;
OUTPUT:
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)
UPDATE:如果你不想整棵树,真正的树,不过是树而只是它的一个子树的一部分,当然你也可以改变条件位:
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
;
此数据库结构是否“锁定”?我想不出任何使用标准SQL进行这种操作的高性能方式(7级自连接并不是我建议的) – 2012-04-02 09:29:32
它看起来像[ltree](http://www.postgresql。 org/docs/current/static/ltree.html)模块是为了解决 – 2012-04-02 10:34:49
@JoachimIsaksson 7个自连接有什么问题..它是完全合理的,如果层数保证;)但我不明白什么是*预期目标* - 结果应该是行还是列? – Aprillion 2012-04-02 10:55:15