如何在PostgreSQL中选择所有带层次的表的层次结构?

问题描述 投票:1回答:2

我此刻有一个问题。我有一个叫places的表,结构是这样的。

  • id
  • parent_id
  • 名称

我想做一个选择,来拥有这个表的所有层次结构。有一个数据的小例子。

(1, null, '123 Barclay St')
(2, 1, 'Floor 1')
(3, 1, 'Floor 2')
(4, 1, 'Floor 3')
(5, 2, 'Hall 1')
(6, 2, 'Room 1')
(7, 2, 'Room 2')
(8, 3, 'Room 3')
(9, null, '10 Thames St')

很明显,表中的顺序不是这样的。

所以我想用我的SELECT得到这个结果(有9行)。

123 Barclay St
   Floor 1
      Hall 1
      Room 1
      Room 2
   Floor 2
      Room 3
   Floor 3
10 Thames St

而不是这个结果(我已经知道如何得到) 。

10 Thames St
123 Barclay St
   Floor 1
   Floor 2
   Floor 3
      Hall 1
      Room 1
      Room 2
      Room 3

如果你能帮助我,我提前感谢你。

sql postgresql hierarchical-data recursive-query
2个回答
2
投票

这里有一个使用递归CTE的解决方案。

WITH RECURSIVE cte AS (
    SELECT LPAD(id::text, 3, '0') AS marker, '   ' AS buffer,
        id, parent_id, name::text
    FROM yourTable t WHERE parent_id IS NULL
    FROM yourTable t WHERE parent_id IS NULL
    UNION ALL
        SELECT t2.marker || ':' || LPAD(t1.parent_id::text, 3, '0') || ':' ||
            LPAD(t1.id::text, 3, '0') AS marker,
            t2.buffer || '   ', t1.id, t1.parent_id, t2.buffer || t1.name
    FROM yourTable t1
    INNER JOIN cte t2
        ON t1.parent_id = t2.id
)

SELECT name FROM cte ORDER BY marker;

enter image description here

演示

这里的基本思想是建立路径字符串,跟踪从每个节点到其根节点的完整路径(根节点由一个节点给出,其 parent_idNULL). 然后,我们只需做一个 ORDER BY 在这个路径上生成你想要的订单。


1
投票

你还没有提供你已经想好的查询。但是--据我所知,你想要一个递归树结构。

https:/www.db-fiddle.comfog5HZDHBhBRmP1cDnqgCBB1

CREATE TABLE rooms (
  id INTEGER, parent_id INTEGER, name TEXT
);

INSERT INTO rooms VALUES
(1, null, '123 Barclay St'),
(2, 1, 'Floor 1'),
(3, 1, 'Floor 2'),
(4, 1, 'Floor 3'),
(5, 2, 'Hall 1'),
(6, 2, 'Room 1'),
(7, 2, 'Room 2'),
(8, 3, 'Room 3'),
(9, null, '10 Thames St');

和查询。

WITH RECURSIVE tree AS (
    SELECT
        rooms.id,
        rooms.parent_id,
        rooms.name
    FROM
        rooms
    WHERE
        parent_id IS NULL
    UNION ALL
    SELECT
        rooms.id,
        rooms.parent_id,
        rooms.name
    FROM
        tree
        JOIN rooms ON rooms.parent_id = tree.id
)
SELECT
    *
FROM
    tree;

https:/www.postgresql.orgdocscurrentstaticqueries-with.html

© www.soinside.com 2019 - 2024. All rights reserved.