具有递归和默认值的树
Tree with recursive and default
使用 Postgres。
我有一个pricelists
CREATE TABLE pricelists(
id SERIAL PRIMARY KEY,
name TEXT,
parent_id INTEGER REFERENCES pricelists
);
和另一个 table、prices
,引用它
CREATE TABLE prices(
pricelist_id INTEGER REFERENCES pricelists,
name TEXT,
value INTEGER NOT NULL,
PRIMARY KEY (pricelist_id, name)
);
- Parent 价目表
id=1
可能有 10 个价格。
- 价目表
id=2
作为 parent 的 child 1
可能有 5 个价格覆盖相同价格的 parent 1
个价格名字.
- Child 价格表
id=3
作为价格表的 child 2
可能有 2 个价格覆盖 child 2
的价格相同的价格名称。
因此当我询问 child 3
价格时,我想得到
- child
3
和 的所有价格
- 他parent(child
2
)的那些价格在child3
和 中不存在
- 所有 parent
1
直到现在才存在的价格。
可以更改架构以提高效率。
示例:
如果
SELECT pl.id AS id, pl.parent_id AS parent, p.name AS price_name, value
FROM pricelists pl
JOIN prices p ON pl.id = p.pricelist_id;
给予
| id | parent | price_name | value |
|----------|:-------------:|------------:|------------:|
| 1 | 1 | bb | 10 |
| 1 | 1 | cc | 10 |
| 2 | 1 | aa | 20 |
| 2 | 1 | bb | 20 |
| 3 | 2 | aa | 30 |
然后我正在寻找一种获取 pricelist_id = 3
价格的方法,该价格会给我
| id | parent | price_name | value |
|----------|:-------------:|------------:|------------:|
| 1 | 1 | cc | 10 |
| 2 | 1 | bb | 20 |
| 3 | 2 | aa | 30 |
WITH RECURSIVE cte AS (
SELECT id, name, parent_id, 1 AS lvl
FROM pricelists
WHERE id = 3 -- provide your id here
UNION ALL
SELECT pl.id, pl.name, pl.parent_id, c.lvl + 1
FROM cte c
JOIN pricelists pl ON pl.id = c.parent_id
)
SELECT DISTINCT ON (p.price_name)
c.id, c.parent_id, p.price_name, p.value
FROM cte c
JOIN prices p ON p.pricelist_id = c.id
ORDER BY p.price_name, c.lvl; -- lower lvl beats higher level
像这里一样使用 recursive CTE:
- Total children values based on parent
- Recursive SELECT query to return rates of arbitrary depth?
有很多个相关答案。
最后加入一次价格,更便宜
使用DISTINCT ON
得到"greatest per group":
- Select first row in each GROUP BY group?
使用 Postgres。
我有一个pricelists
CREATE TABLE pricelists(
id SERIAL PRIMARY KEY,
name TEXT,
parent_id INTEGER REFERENCES pricelists
);
和另一个 table、prices
,引用它
CREATE TABLE prices(
pricelist_id INTEGER REFERENCES pricelists,
name TEXT,
value INTEGER NOT NULL,
PRIMARY KEY (pricelist_id, name)
);
- Parent 价目表
id=1
可能有 10 个价格。 - 价目表
id=2
作为 parent 的 child1
可能有 5 个价格覆盖相同价格的 parent1
个价格名字. - Child 价格表
id=3
作为价格表的 child2
可能有 2 个价格覆盖 child2
的价格相同的价格名称。
因此当我询问 child 3
价格时,我想得到
- child
3
和 的所有价格
- 他parent(child
2
)的那些价格在child3
和 中不存在
- 所有 parent
1
直到现在才存在的价格。
可以更改架构以提高效率。
示例:
如果
SELECT pl.id AS id, pl.parent_id AS parent, p.name AS price_name, value
FROM pricelists pl
JOIN prices p ON pl.id = p.pricelist_id;
给予
| id | parent | price_name | value |
|----------|:-------------:|------------:|------------:|
| 1 | 1 | bb | 10 |
| 1 | 1 | cc | 10 |
| 2 | 1 | aa | 20 |
| 2 | 1 | bb | 20 |
| 3 | 2 | aa | 30 |
然后我正在寻找一种获取 pricelist_id = 3
价格的方法,该价格会给我
| id | parent | price_name | value |
|----------|:-------------:|------------:|------------:|
| 1 | 1 | cc | 10 |
| 2 | 1 | bb | 20 |
| 3 | 2 | aa | 30 |
WITH RECURSIVE cte AS (
SELECT id, name, parent_id, 1 AS lvl
FROM pricelists
WHERE id = 3 -- provide your id here
UNION ALL
SELECT pl.id, pl.name, pl.parent_id, c.lvl + 1
FROM cte c
JOIN pricelists pl ON pl.id = c.parent_id
)
SELECT DISTINCT ON (p.price_name)
c.id, c.parent_id, p.price_name, p.value
FROM cte c
JOIN prices p ON p.pricelist_id = c.id
ORDER BY p.price_name, c.lvl; -- lower lvl beats higher level
像这里一样使用 recursive CTE:
- Total children values based on parent
- Recursive SELECT query to return rates of arbitrary depth?
有很多个相关答案。
最后加入一次价格,更便宜
使用
DISTINCT ON
得到"greatest per group":- Select first row in each GROUP BY group?