如何在 PostgreSQL 中 select 具有级别的 table 的所有层次结构
How to select all the hierarchy of a table with levels in PostgreSQL
我现在有问题。
我有一个名为 places 的 table 结构:
- id
- parent_id
- 名字
我想做一个选择来拥有这个 table 的所有层次结构。有一个数据的小例子:
(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')
显然 table 中的顺序不是这个。
所以我想用我的 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
如果你能帮助我,我先谢谢你了。
这是一个使用递归 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;
这里的基本思想是构建路径字符串,跟踪从每个节点返回其根的完整路径(根由 parent_id
为 NULL
的节点给出)。然后,我们简单地在这个路径上做一个ORDER BY
来生成你想要的顺序。
您还没有提供您已经提出的查询。但是 - 据我所知你想要一个递归树结构。
https://www.db-fiddle.com/f/og5HZDHBhBRmP1cDnqgCBB/1
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.org/docs/current/static/queries-with.html
我现在有问题。 我有一个名为 places 的 table 结构:
- id
- parent_id
- 名字
我想做一个选择来拥有这个 table 的所有层次结构。有一个数据的小例子:
(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')
显然 table 中的顺序不是这个。
所以我想用我的 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
如果你能帮助我,我先谢谢你了。
这是一个使用递归 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;
这里的基本思想是构建路径字符串,跟踪从每个节点返回其根的完整路径(根由 parent_id
为 NULL
的节点给出)。然后,我们简单地在这个路径上做一个ORDER BY
来生成你想要的顺序。
您还没有提供您已经提出的查询。但是 - 据我所知你想要一个递归树结构。
https://www.db-fiddle.com/f/og5HZDHBhBRmP1cDnqgCBB/1
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.org/docs/current/static/queries-with.html