使用Postgres。
我有pricelists
CREATE TABLE pricelists(
id SERIAL PRIMARY KEY,
name TEXT,
parent_id INTEGER REFERENCES pricelists
);
和另一个表prices
,引用它
CREATE TABLE prices(
pricelist_id INTEGER REFERENCES pricelists,
name TEXT,
value INTEGER NOT NULL,
PRIMARY KEY (pricelist_id, name)
);
id=1
可能有10个价格。id=2
的孩子的价目表1
可能有5个价格,这些价格会覆盖相同价格名称的父1
价格。id=3
与价格表2
的孩子一样可能有2个价格会覆盖相同价格名称的子2
价格。因此,当我要求孩子3
价格时,我想得到
3
和2
)的价格在子3
和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 |
答案 0 :(得分:1)
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:
有许多与相关的答案。
最后加入价格,这样便宜。
使用DISTINCT ON
获得“每组最佳”: