我在 PostgreSQL 9.4 中存储了一个典型的树结构作为邻接列表:
gear_category (
id INTEGER PRIMARY KEY,
name TEXT,
parent_id INTEGER
);
Run Code Online (Sandbox Code Playgroud)
以及附加到类别的项目列表:
gear_item (
id INTEGER PRIMARY KEY,
name TEXT,
category_id INTEGER REFERENCES gear_category
);
Run Code Online (Sandbox Code Playgroud)
任何类别都可以附加装备物品,而不仅仅是树叶。
出于速度原因,我想预先计算有关每个类别的一些数据,我将使用这些数据来生成物化视图。
期望的输出:
speedy_materialized_view (
gear_category_id INTEGER,
count_direct_child_items INTEGER,
count_recursive_child_items INTEGER
);
Run Code Online (Sandbox Code Playgroud)
count_recursive_child_items是附加到当前类别或任何子类别的 GearItems 的累积数量。每个类别应占一行,任何为 0 的计数都为 0。
为了计算这个,我们需要使用递归 CTE 来遍历树:
WITH RECURSIVE children(id, parent_id) AS (
--base case
SELECT gear_category.id AS id, gear_category.parent_id AS parent_id
FROM gear_category
WHERE gear_category.id = 37 -- setting this to id includes current object …Run Code Online (Sandbox Code Playgroud) 具有这种简单的多对多自引用结构。
一个项目通过表拥有其他项目joins:
CREATE TABLE items (
item_id serial PRIMARY KEY
, title text
);
CREATE TABLE joins (
id serial PRIMARY KEY
, item_id int
, child_id int
);
INSERT INTO items (item_id, title) VALUES
(1, 'PARENT')
, (2, 'LEVEL 2')
, (3, 'LEVEL 3.1')
, (4, 'LEVEL 4.1')
, (5, 'LEVEL 4.2')
, (6, 'LEVEL 3.2')
;
INSERT INTO joins (item_id, child_id) VALUES
(1, 2)
, (2, 3)
, (3, 4)
, (3, 5)
, (2, 6) …Run Code Online (Sandbox Code Playgroud)