查询以检索递归定义的父项列表

时间:2015-01-23 13:52:01

标签: sql postgresql

我正在尝试获取包含给定记录的所有父亲的ID的ID列表。

表:carrier_products(id,carrier_product_id)

到目前为止,我已经提出了这个

carrier_products.id IN
                 (WITH RECURSIVE tree(id, carrier_product_id) AS (
                  SELECT cp.id, cp.carrier_product_id FROM carrier_products cp WHERE cp.id = ?
                    UNION
                      SELECT cp.id, cp.carrier_product_id
                      FROM carrier_products cp JOIN tree ON cp.carrier_product_id = tree.id
                    )
                  SELECT id FROM tree)

但这不能正常,有什么建议吗?

1 个答案:

答案 0 :(得分:1)

您必须小心确切要检索的内容。在这里,您需要一个包含所有祖先的表,因此您使用WITH RECURSIVE创建的表应该只有一个字段(id)。另外,请注意递归的结束条件(null值的测试)。这是一个解决方案:

postgres@localhost testdb=# create table carrier_products(id integer unique not null, carrier_product_id integer);
CREATE TABLE
Temps : 33,361 ms

postgres@localhost testdb=# insert into carrier_products(id, carrier_product_id) values (0, null);
INSERT 0 1
Temps : 3,005 ms
postgres@localhost testdb=# insert into carrier_products(id, carrier_product_id) values (1, 0);
INSERT 0 1
Temps : 1,151 ms
postgres@localhost testdb=# insert into carrier_products(id, carrier_product_id) values (2, 0);
INSERT 0 1
Temps : 0,978 ms
postgres@localhost testdb=# insert into carrier_products(id, carrier_product_id) values (3, 1);
INSERT 0 1
Temps : 0,676 ms
postgres@localhost testdb=# select * from carrier_products;
 id | carrier_product_id
----+--------------------
  0 |               NULL
  1 |                  0
  2 |                  0
  3 |                  1
(4 lignes)

postgres@localhost testdb=# WITH RECURSIVE tree(id) AS (
  SELECT cp.carrier_product_id FROM carrier_products cp WHERE cp.id = 3
  UNION
  SELECT cp.carrier_product_id
  FROM carrier_products cp JOIN tree ON cp.id = tree.id and cp.carrier_product_id is not null
)
SELECT id FROM tree;

 id
----
  1
  0