如何在PostgreSQL中选择具有级别的表的所有层次结构
我现在有个问题。 我有一张名为places的桌子,其结构如下:如何在PostgreSQL中选择具有级别的表的所有层次结构,sql,postgresql,hierarchical-data,recursive-query,Sql,Postgresql,Hierarchical Data,Recursive Query,我现在有个问题。 我有一张名为places的桌子,其结构如下: 身份证 家长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
- 身份证
- 家长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行)得到这个结果:
而不是这个结果(我已经知道如何得到):
如果您能帮助我,我将提前感谢您。这里有一个使用递归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;
这里的基本思想是构建路径字符串,跟踪从每个节点到其根的完整路径(根由其
父\u id
为NULL
的节点给出)。然后,我们只需在此路径上按进行一次排序即可生成所需的顺序。下面是一个使用递归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;
这里的基本思想是构建路径字符串,跟踪从每个节点到其根的完整路径(根由其
父\u id
为NULL
的节点给出)。然后,我们只需在此路径上按进行一次排序,即可生成所需的订单。您还没有提供您已经提出的查询。但是-据我所知,您需要一个递归树结构
以及查询:
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;
您尚未提供您已经提出的查询。但是-据我所知,您需要一个递归树结构 以及查询:
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;
我尝试了此解决方案,并验证了此解决方案。非常感谢。@S.Kaio使用数组更简单一点:而且每个元素的路径都很容易使用。@Abelisto我测试了您的解决方案,非常感谢。感谢您的帮助:)我尝试了此解决方案,并验证了此解决方案。非常感谢。@S.Kaio使用数组更简单一点:而且每个元素的路径都很容易使用。@Abelisto我测试了您的解决方案,非常感谢。谢谢你的帮助:)很抱歉,如果我没有提供我已经提出的问题,但是我说了我不想要的结果。在这篇文章之前我做了你的查询,这个查询给了我我所说的坏结果。它返回如下层次结构:巴克莱大街1楼,2楼,3楼,1号大厅。。。但不是每个级别的所有层次结构。我非常感谢你,因为你试图帮助我。:)对不起,如果我没有提供我已经提出的问题,但是我说了我不想要的结果。在这篇文章之前我做了你的查询,这个查询给了我我所说的坏结果。它返回如下层次结构:巴克莱大街1楼,2楼,3楼,1号大厅。。。但不是每个级别的所有层次结构。我非常感谢你,因为你试图帮助我。:)
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;