【问题标题】:Postgresql. How save first id for all children in recursive query?PostgreSQL。如何在递归查询中为所有孩子保存第一个 ID?
【发布时间】:2017-10-27 09:13:02
【问题描述】:

我有构建树的递归查询,与

CREATE TABLE geo (
    id int not null primary key, 
    parent_id int references geo(id),  
    name varchar(1000)
);

INSERT INTO geo 
(id, parent_id, name) 
VALUES 
(1, null, 'Планета Земля'),
(2, 1, 'Континент Евразия'),
(3, 1, 'Континент Северная Америка'),
(4, 2, 'Европа'),
(5, 4, 'Россия'),
(6, 4, 'Германия'),
(7, 5, 'Москва'),
(8, 5, 'Санкт-Петербург'),
(9, 6, 'Берлин');

WITH RECURSIVE r AS (
   SELECT id, parent_id, name, 1 AS level
  FROM geo
   WHERE id = 4

   UNION ALL

   SELECT geo.id, geo.parent_id, geo.name, r.level + 1 AS level
   FROM geo
      JOIN r
          ON geo.parent_id = r.id
)

SELECT * FROM r;

如何为组中的每个孩子选择根 ID? 现在结果:

id | parent_id |      name       | level  
----+-----------+-----------------+-------  
  4 |         2 | Европа          |     1  
  5 |         4 | Россия          |     2  
  6 |         4 | Германия        |     2  
  7 |         5 | Москва          |     3  
  8 |         5 | Санкт-Петербург |     3  
  9 |         6 | Берлин          |     3  

但我需要,一些东西:

 id | parent_id |      name       | level| root_id   
----+-----------+-----------------+------+---------  
  4 |         2 | Европа          |     1| null  
  5 |         4 | Россия          |     2| 4  
  6 |         4 | Германия        |     2| 4  
  7 |         5 | Москва          |     3| 4  
  8 |         5 | Санкт-Петербург |     3| 4  
  9 |         6 | Берлин          |     3| 4  

【问题讨论】:

    标签: sql postgresql recursion


    【解决方案1】:

    你可以从非递归部分继承它,类似于你对level所做的:

    WITH RECURSIVE r AS (
      SELECT id, parent_id, name, 1 AS level, id as root
      FROM geo
      WHERE id = 4
    
      UNION ALL
    
      SELECT geo.id, geo.parent_id, geo.name, r.level + 1 AS level, r.root
      FROM geo
        JOIN r ON geo.parent_id = r.id
    )
    SELECT id, parent_id, name, level, 
           nullif(root, id) as root 
    FROM r;
    

    nullif() 是必需的,因为您想在 id = root 所在的行显示null

    在线示例:http://rextester.com/BPP29069

    【讨论】:

      猜你喜欢
      • 2010-11-02
      • 1970-01-01
      • 1970-01-01
      • 2011-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-12
      相关资源
      最近更新 更多